From 9ae21dfd5dcb05400171c5d6bc9e541288a6b6cd Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 4 Sep 2017 12:26:58 +0200 Subject: [PATCH] reattaching cells with different IDs and PRB --- lib/include/srslte/phy/phch/pdsch.h | 1 + lib/include/srslte/phy/phch/pusch.h | 3 +- lib/src/phy/enb/enb_ul.c | 2 +- lib/src/phy/phch/pdsch.c | 36 ++++++++++++++++------- lib/src/phy/phch/pusch.c | 45 +++++++++++++++++++---------- lib/src/phy/ue/ue_ul.c | 2 +- srsue/hdr/phy/phch_recv.h | 6 +++- srsue/hdr/upper/rrc.h | 1 + srsue/src/main.cc | 1 - srsue/src/phy/phch_recv.cc | 19 ++++++------ srsue/src/phy/phch_worker.cc | 2 +- srsue/src/upper/rrc.cc | 28 +++++++++++------- 12 files changed, 94 insertions(+), 52 deletions(-) diff --git a/lib/include/srslte/phy/phch/pdsch.h b/lib/include/srslte/phy/phch/pdsch.h index 4f396dd6d..b163f45bf 100644 --- a/lib/include/srslte/phy/phch/pdsch.h +++ b/lib/include/srslte/phy/phch/pdsch.h @@ -49,6 +49,7 @@ typedef struct { srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; + uint32_t cell_id; bool sequence_generated; } srslte_pdsch_user_t; diff --git a/lib/include/srslte/phy/phch/pusch.h b/lib/include/srslte/phy/phch/pusch.h index 3e7a5d258..834750e38 100644 --- a/lib/include/srslte/phy/phch/pusch.h +++ b/lib/include/srslte/phy/phch/pusch.h @@ -62,6 +62,7 @@ typedef struct { typedef struct { srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; + uint32_t cell_id; bool sequence_generated; } srslte_pusch_user_t; @@ -121,7 +122,7 @@ SRSLTE_API int srslte_pusch_cfg(srslte_pusch_t *q, SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti); -SRSLTE_API void srslte_pusch_clear_rnti(srslte_pusch_t *q, +SRSLTE_API void srslte_pusch_free_rnti(srslte_pusch_t *q, uint16_t rnti); SRSLTE_API int srslte_pusch_encode(srslte_pusch_t *q, diff --git a/lib/src/phy/enb/enb_ul.c b/lib/src/phy/enb/enb_ul.c index 03b10e7cd..f756c021f 100644 --- a/lib/src/phy/enb/enb_ul.c +++ b/lib/src/phy/enb/enb_ul.c @@ -220,7 +220,7 @@ void srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, uint16_t rnti) if (q->users[rnti]) { free(q->users[rnti]); q->users[rnti] = NULL; - srslte_pusch_clear_rnti(&q->pusch, rnti); + srslte_pusch_free_rnti(&q->pusch, rnti); } } diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 4e28a7832..a10be3e09 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "srslte/phy/phch/pdsch.h" #include "prb_dl.h" #include "srslte/phy/utils/debug.h" @@ -386,17 +387,27 @@ int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) { uint32_t i; uint32_t rnti_idx = q->is_ue?0:rnti; - if (!q->users[rnti_idx]) { - q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t)); - if (q->users[rnti_idx]) { - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pdsch(&q->users[rnti_idx]->seq[i], rnti, 0, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - return SRSLTE_ERROR; - } + if (!q->users[rnti_idx] || q->is_ue) { + if (!q->users[rnti_idx]) { + q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t)); + if(!q->users[rnti_idx]) { + perror("calloc"); + return -1; + } + } + for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + if (srslte_sequence_pdsch(&q->users[rnti_idx]->seq[i], rnti, 0, 2 * i, q->cell.id, + q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) + { + fprintf(stderr, "Error initializing PDSCH scrambling sequence\n"); + srslte_pdsch_free_rnti(q, rnti); + return SRSLTE_ERROR; } - q->users[rnti_idx]->sequence_generated = true; } + q->users[rnti_idx]->cell_id = q->cell.id; + q->users[rnti_idx]->sequence_generated = true; + } else { + fprintf(stderr, "Error generating PDSCH sequence: rnti=0x%x already generated\n", rnti); } return SRSLTE_SUCCESS; } @@ -431,7 +442,12 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, static srslte_sequence_t *get_user_sequence(srslte_pdsch_t *q, uint16_t rnti, uint32_t sf_idx, uint32_t len) { uint32_t rnti_idx = q->is_ue?0:rnti; - if (q->users[rnti_idx] && q->users[rnti_idx]->sequence_generated) { + + // The scrambling sequence is pregenerated for all RNTIs in the eNodeB but only for C-RNTI in the UE + if (q->users[rnti_idx] && q->users[rnti_idx]->sequence_generated && + q->users[rnti_idx]->cell_id == q->cell.id && + ((rnti >= SRSLTE_CRNTI_START && rnti < SRSLTE_CRNTI_END) || !q->is_ue)) + { return &q->users[rnti_idx]->seq[sf_idx]; } else { srslte_sequence_pdsch(&q->tmp_seq, rnti, 0, 2 * sf_idx, q->cell.id, len); diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index 237036a57..6769f43d4 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -293,10 +293,10 @@ void srslte_pusch_free(srslte_pusch_t *q) { if (q->users) { if (q->is_ue) { - srslte_pusch_clear_rnti(q, 0); + srslte_pusch_free_rnti(q, 0); } else { for (int rnti=0;rntiusers); @@ -435,25 +435,33 @@ int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti) { uint32_t i; uint32_t rnti_idx = q->is_ue?0:rnti; - - if (!q->users[rnti_idx]) { - q->users[rnti_idx] = calloc(1, sizeof(srslte_pusch_user_t)); - if (q->users[rnti_idx]) { - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { - if (srslte_sequence_pusch(&q->users[rnti_idx]->seq[i], rnti, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - fprintf(stderr, "Error initializing PUSCH scrambling sequence\n"); - srslte_pusch_clear_rnti(q, rnti); - return SRSLTE_ERROR; - } + + if (!q->users[rnti_idx] || q->is_ue) { + if (!q->users[rnti_idx]) { + q->users[rnti_idx] = calloc(1, sizeof(srslte_pusch_user_t)); + if (!q->users[rnti_idx]) { + perror("calloc"); + return -1; } - q->users[rnti_idx]->sequence_generated = true; } + for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + if (srslte_sequence_pusch(&q->users[rnti_idx]->seq[i], rnti, 2 * i, q->cell.id, + q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) + { + fprintf(stderr, "Error initializing PUSCH scrambling sequence\n"); + srslte_pusch_free_rnti(q, rnti); + return SRSLTE_ERROR; + } + } + q->users[rnti_idx]->cell_id = q->cell.id; + q->users[rnti_idx]->sequence_generated = true; + } else { + fprintf(stderr, "Error generating PUSCH sequence: rnti=0x%x already generated\n", rnti); } return SRSLTE_SUCCESS; } -void srslte_pusch_clear_rnti(srslte_pusch_t *q, uint16_t rnti) { +void srslte_pusch_free_rnti(srslte_pusch_t *q, uint16_t rnti) { uint32_t rnti_idx = q->is_ue?0:rnti; @@ -470,7 +478,12 @@ void srslte_pusch_clear_rnti(srslte_pusch_t *q, uint16_t rnti) { static srslte_sequence_t *get_user_sequence(srslte_pusch_t *q, uint16_t rnti, uint32_t sf_idx, uint32_t len) { uint32_t rnti_idx = q->is_ue?0:rnti; - if (q->users[rnti_idx] && q->users[rnti_idx]->sequence_generated) { + + // The scrambling sequence is pregenerated for all RNTIs in the eNodeB but only for C-RNTI in the UE + if (q->users[rnti_idx] && q->users[rnti_idx]->sequence_generated && + q->users[rnti_idx]->cell_id == q->cell.id && + ((rnti >= SRSLTE_CRNTI_START && rnti < SRSLTE_CRNTI_END) || !q->is_ue)) + { return &q->users[rnti_idx]->seq[sf_idx]; } else { srslte_sequence_pusch(&q->tmp_seq, rnti, 2 * sf_idx, q->cell.id, len); diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 2792cff09..82f0eec91 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -446,7 +446,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, q->pusch_cfg.grant.n_prb_tilde, q->sf_symbols); } else { - + if (srslte_refsignal_dmrs_pusch_gen(&q->signals, q->pusch_cfg.grant.L_prb, q->pusch_cfg.sf_idx, q->pusch_cfg.grant.ncs_dmrs, diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index c50252ae2..5bf9142d0 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -111,7 +111,11 @@ private: sync_metrics_t metrics; enum { - IDLE, CELL_SEARCH, CELL_MEASURE, CELL_SELECT, CELL_CAMP + IDLE = 0, + CELL_SEARCH, + CELL_SELECT, + CELL_MEASURE, + CELL_CAMP } phy_state; bool is_in_idle; diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 4eeb1f7d9..bafbdc03c 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -137,6 +137,7 @@ private: float rsrp; bool has_valid_sib1; bool has_valid_sib2; + bool in_sync; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2; } cell_t; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 78356c478..d2a75604d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -349,7 +349,6 @@ int main(int argc, char *argv[]) all_args_t args; parse_args(&args, argc, argv); - srsue_instance_type_t type = LTE; ue_base *ue = ue_base::get_instance(type); if (!ue) { diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6142cfaf0..55389059b 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -433,8 +433,7 @@ void phch_recv::cell_search_start() { cell_search_in_progress = true; cur_earfcn_index = -1; cell_search_next(); - log_h->console("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); - log_h->info("Cell Search: Starting procedure...\n"); + log_h->info("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); } else { log_h->info("Empty EARFCN list. Stopping cell search...\n"); log_h->console("Empty EARFCN list. Stopping cell search...\n"); @@ -445,12 +444,12 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { // Check if we are already camping in this cell if (earfcn == current_earfcn && this->cell.id == cell.id) { - log_h->info("Cell Select: Already in Cell EARFCN=%d\n", earfcn); - cell_search_in_progress = false; + log_h->info("Cell Select: Already in cell EARFCN=%d\n", earfcn); + cell_search_in_progress = false; if (srate_mode != SRATE_CAMP) { set_sampling_rate(); } - if (phy_state != CELL_SELECT) { + if (phy_state < CELL_SELECT) { resync_sfn(); } return true; @@ -491,11 +490,11 @@ bool phch_recv::set_frequency() log_h->info("Set DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n", current_earfcn, dl_freq / 1e6, ul_freq / 1e6); - log_h->console("Tunning to EARFCN=%d, F_dl=%.1f MHz, F_ul=%.1f MHz\n", + log_h->console("Searching cell in DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n", current_earfcn, dl_freq / 1e6, ul_freq / 1e6); - radio_h->set_rx_freq(dl_freq); - radio_h->set_tx_freq(ul_freq); + radio_h->set_rx_freq(dl_freq-4000); + radio_h->set_tx_freq(ul_freq-4000); ul_dl_factor = ul_freq / dl_freq; srslte_ue_sync_reset(&ue_sync); @@ -567,7 +566,7 @@ void phch_recv::run_thread() { srslte_ue_sync_set_agc_period(&ue_sync, 20); if (!cell_search_in_progress) { phy_state = CELL_CAMP; - log_h->console("Sync OK. Camping on cell PCI=%d...\n", cell.id); + log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); } else { measure_cnt = 0; measure_rsrp = 0; @@ -587,9 +586,9 @@ void phch_recv::run_thread() { case CELL_MEASURE: switch(cell_meas_rsrp()) { case 1: + log_h->info("Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000)); - log_h->info("Measured OK. Camping on cell PCI=%d...\n", cell.id); break; case 0: break; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 1d4128d1e..ecbbc8768 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -472,7 +472,7 @@ bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, #endif Info("PDSCH: l_crb=%2d, harq=%d, tbs=%d, mcs=%d, rv=%d, crc=%s, snr=%.1f dB, n_iter=%d%s\n", - grant->nof_prb, harq_pid, + grant->nof_prb, harq_pid, grant->mcs.tbs/8, grant->mcs.idx, rv, ack?"OK":"KO", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 0b3991e16..1b24d05c1 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -30,6 +30,7 @@ #include "srslte/asn1/liblte_rrc.h" #include "upper/rrc.h" #include +#include #include "srslte/common/security.h" #include "srslte/common/bcd_helpers.h" @@ -187,17 +188,21 @@ void rrc::select_next_cell_in_plmn() { rrc_log->info("Selecting cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", known_cells[i].phy_cell.id, known_cells[i].earfcn, known_cells[i].sib1.cell_id); - rrc_log->console("Selecting cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + rrc_log->console("Select cell: PCI=%d, EARFCN=%d, Cell ID=0x%x\n", known_cells[i].phy_cell.id, known_cells[i].earfcn, known_cells[i].sib1.cell_id); // Check that cell satisfies S criteria - if (phy->cell_select(known_cells[i].earfcn, known_cells[i].phy_cell)) { - last_selected_cell = i; - current_cell = &known_cells[i]; - return; - } else { - rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", - known_cells[i].earfcn, known_cells[i].sib1.cell_id); + if (known_cells[i].in_sync) { // %% rsrp > S dbm + // Try to select Cell + if (phy->cell_select(known_cells[i].earfcn, known_cells[i].phy_cell)) + { + last_selected_cell = i; + current_cell = &known_cells[i]; + return; + } else { + rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", + known_cells[i].earfcn, known_cells[i].sib1.cell_id); + } } } } @@ -214,7 +219,8 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { // find if cell_id-earfcn combination already exists for (uint32_t i = 0; i < known_cells.size(); i++) { if (earfcn == known_cells[i].earfcn && phy_cell.id == known_cells[i].phy_cell.id) { - known_cells[i].rsrp = rsrp; + known_cells[i].rsrp = rsrp; + known_cells[i].in_sync = true; current_cell = &known_cells[i]; rrc_log->info("Updating cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", known_cells[i].earfcn, known_cells[i].phy_cell.id, known_cells[i].rsrp); @@ -255,6 +261,7 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { // Detection of physical layer problems (5.3.11.1) void rrc::out_of_sync() { + current_cell->in_sync = false; if (!mac_timers->get(t311)->is_running() && !mac_timers->get(t310)->is_running()) { n310_cnt++; if (n310_cnt == N310) { @@ -268,6 +275,7 @@ void rrc::out_of_sync() { // Recovery of physical layer problems (5.3.11.2) void rrc::in_sync() { + current_cell->in_sync = true; if (mac_timers->get(t310)->is_running()) { n311_cnt++; if (n311_cnt == N311) { @@ -1087,7 +1095,7 @@ void rrc::reset_ue() { mac->pcch_start_rx(); mac_timers->get(safe_reset_timer)->stop(); mac_timers->get(safe_reset_timer)->reset(); - rrc_log->console("RRC Connection released.\n"); + rrc_log->console("RRC Connection Released.\n"); } void rrc::rrc_connection_release() {