reattaching cells with different IDs and PRB

This commit is contained in:
Ismael Gomez 2017-09-04 12:26:58 +02:00
parent a993e72534
commit 9ae21dfd5d
12 changed files with 94 additions and 52 deletions

View File

@ -49,6 +49,7 @@
typedef struct { typedef struct {
srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME];
uint32_t cell_id;
bool sequence_generated; bool sequence_generated;
} srslte_pdsch_user_t; } srslte_pdsch_user_t;

View File

@ -62,6 +62,7 @@ typedef struct {
typedef struct { typedef struct {
srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME]; srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME];
uint32_t cell_id;
bool sequence_generated; bool sequence_generated;
} srslte_pusch_user_t; } 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, SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q,
uint16_t rnti); 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); uint16_t rnti);
SRSLTE_API int srslte_pusch_encode(srslte_pusch_t *q, SRSLTE_API int srslte_pusch_encode(srslte_pusch_t *q,

View File

@ -220,7 +220,7 @@ void srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q, uint16_t rnti)
if (q->users[rnti]) { if (q->users[rnti]) {
free(q->users[rnti]); free(q->users[rnti]);
q->users[rnti] = NULL; q->users[rnti] = NULL;
srslte_pusch_clear_rnti(&q->pusch, rnti); srslte_pusch_free_rnti(&q->pusch, rnti);
} }
} }

View File

@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <srslte/phy/phch/pdsch.h>
#include "srslte/phy/phch/pdsch.h" #include "srslte/phy/phch/pdsch.h"
#include "prb_dl.h" #include "prb_dl.h"
#include "srslte/phy/utils/debug.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 i;
uint32_t rnti_idx = q->is_ue?0:rnti; uint32_t rnti_idx = q->is_ue?0:rnti;
if (!q->users[rnti_idx]) { if (!q->users[rnti_idx] || q->is_ue) {
q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t)); if (!q->users[rnti_idx]) {
if (q->users[rnti_idx]) { q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t));
for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { if(!q->users[rnti_idx]) {
if (srslte_sequence_pdsch(&q->users[rnti_idx]->seq[i], rnti, 0, 2 * i, q->cell.id, perror("calloc");
q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { return -1;
return SRSLTE_ERROR;
}
} }
q->users[rnti_idx]->sequence_generated = true;
} }
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]->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; 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) 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; 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]; return &q->users[rnti_idx]->seq[sf_idx];
} else { } else {
srslte_sequence_pdsch(&q->tmp_seq, rnti, 0, 2 * sf_idx, q->cell.id, len); srslte_sequence_pdsch(&q->tmp_seq, rnti, 0, 2 * sf_idx, q->cell.id, len);

View File

@ -293,10 +293,10 @@ void srslte_pusch_free(srslte_pusch_t *q) {
if (q->users) { if (q->users) {
if (q->is_ue) { if (q->is_ue) {
srslte_pusch_clear_rnti(q, 0); srslte_pusch_free_rnti(q, 0);
} else { } else {
for (int rnti=0;rnti<SRSLTE_SIRNTI;rnti++) { for (int rnti=0;rnti<SRSLTE_SIRNTI;rnti++) {
srslte_pusch_clear_rnti(q, rnti); srslte_pusch_free_rnti(q, rnti);
} }
} }
free(q->users); free(q->users);
@ -435,25 +435,33 @@ int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti) {
uint32_t i; uint32_t i;
uint32_t rnti_idx = q->is_ue?0:rnti; uint32_t rnti_idx = q->is_ue?0:rnti;
if (!q->users[rnti_idx]) { if (!q->users[rnti_idx] || q->is_ue) {
q->users[rnti_idx] = calloc(1, sizeof(srslte_pusch_user_t)); if (!q->users[rnti_idx]) {
if (q->users[rnti_idx]) { q->users[rnti_idx] = calloc(1, sizeof(srslte_pusch_user_t));
for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { if (!q->users[rnti_idx]) {
if (srslte_sequence_pusch(&q->users[rnti_idx]->seq[i], rnti, 2 * i, q->cell.id, perror("calloc");
q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { return -1;
fprintf(stderr, "Error initializing PUSCH scrambling sequence\n");
srslte_pusch_clear_rnti(q, rnti);
return SRSLTE_ERROR;
}
} }
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; 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; 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) 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; 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]; return &q->users[rnti_idx]->seq[sf_idx];
} else { } else {
srslte_sequence_pusch(&q->tmp_seq, rnti, 2 * sf_idx, q->cell.id, len); srslte_sequence_pusch(&q->tmp_seq, rnti, 2 * sf_idx, q->cell.id, len);

View File

@ -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->pusch_cfg.grant.n_prb_tilde,
q->sf_symbols); q->sf_symbols);
} else { } else {
if (srslte_refsignal_dmrs_pusch_gen(&q->signals, q->pusch_cfg.grant.L_prb, if (srslte_refsignal_dmrs_pusch_gen(&q->signals, q->pusch_cfg.grant.L_prb,
q->pusch_cfg.sf_idx, q->pusch_cfg.sf_idx,
q->pusch_cfg.grant.ncs_dmrs, q->pusch_cfg.grant.ncs_dmrs,

View File

@ -111,7 +111,11 @@ private:
sync_metrics_t metrics; sync_metrics_t metrics;
enum { enum {
IDLE, CELL_SEARCH, CELL_MEASURE, CELL_SELECT, CELL_CAMP IDLE = 0,
CELL_SEARCH,
CELL_SELECT,
CELL_MEASURE,
CELL_CAMP
} phy_state; } phy_state;
bool is_in_idle; bool is_in_idle;

View File

@ -137,6 +137,7 @@ private:
float rsrp; float rsrp;
bool has_valid_sib1; bool has_valid_sib1;
bool has_valid_sib2; bool has_valid_sib2;
bool in_sync;
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1;
LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2;
} cell_t; } cell_t;

View File

@ -349,7 +349,6 @@ int main(int argc, char *argv[])
all_args_t args; all_args_t args;
parse_args(&args, argc, argv); parse_args(&args, argc, argv);
srsue_instance_type_t type = LTE; srsue_instance_type_t type = LTE;
ue_base *ue = ue_base::get_instance(type); ue_base *ue = ue_base::get_instance(type);
if (!ue) { if (!ue) {

View File

@ -433,8 +433,7 @@ void phch_recv::cell_search_start() {
cell_search_in_progress = true; cell_search_in_progress = true;
cur_earfcn_index = -1; cur_earfcn_index = -1;
cell_search_next(); cell_search_next();
log_h->console("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size()); log_h->info("Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
log_h->info("Cell Search: Starting procedure...\n");
} else { } else {
log_h->info("Empty EARFCN list. Stopping cell search...\n"); log_h->info("Empty EARFCN list. Stopping cell search...\n");
log_h->console("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 // Check if we are already camping in this cell
if (earfcn == current_earfcn && this->cell.id == cell.id) { if (earfcn == current_earfcn && this->cell.id == cell.id) {
log_h->info("Cell Select: Already in Cell EARFCN=%d\n", earfcn); log_h->info("Cell Select: Already in cell EARFCN=%d\n", earfcn);
cell_search_in_progress = false; cell_search_in_progress = false;
if (srate_mode != SRATE_CAMP) { if (srate_mode != SRATE_CAMP) {
set_sampling_rate(); set_sampling_rate();
} }
if (phy_state != CELL_SELECT) { if (phy_state < CELL_SELECT) {
resync_sfn(); resync_sfn();
} }
return true; 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", log_h->info("Set DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n",
current_earfcn, dl_freq / 1e6, ul_freq / 1e6); 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); current_earfcn, dl_freq / 1e6, ul_freq / 1e6);
radio_h->set_rx_freq(dl_freq); radio_h->set_rx_freq(dl_freq-4000);
radio_h->set_tx_freq(ul_freq); radio_h->set_tx_freq(ul_freq-4000);
ul_dl_factor = ul_freq / dl_freq; ul_dl_factor = ul_freq / dl_freq;
srslte_ue_sync_reset(&ue_sync); srslte_ue_sync_reset(&ue_sync);
@ -567,7 +566,7 @@ void phch_recv::run_thread() {
srslte_ue_sync_set_agc_period(&ue_sync, 20); srslte_ue_sync_set_agc_period(&ue_sync, 20);
if (!cell_search_in_progress) { if (!cell_search_in_progress) {
phy_state = CELL_CAMP; 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 { } else {
measure_cnt = 0; measure_cnt = 0;
measure_rsrp = 0; measure_rsrp = 0;
@ -587,9 +586,9 @@ void phch_recv::run_thread() {
case CELL_MEASURE: case CELL_MEASURE:
switch(cell_meas_rsrp()) { switch(cell_meas_rsrp()) {
case 1: case 1:
log_h->info("Measured OK. Camping on cell PCI=%d...\n", cell.id);
phy_state = CELL_CAMP; phy_state = CELL_CAMP;
rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000)); 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; break;
case 0: case 0:
break; break;

View File

@ -472,7 +472,7 @@ bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload,
#endif #endif
Info("PDSCH: l_crb=%2d, harq=%d, tbs=%d, mcs=%d, rv=%d, crc=%s, snr=%.1f dB, n_iter=%d%s\n", 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, grant->mcs.tbs/8, grant->mcs.idx, rv,
ack?"OK":"KO", ack?"OK":"KO",
10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)),

View File

@ -30,6 +30,7 @@
#include "srslte/asn1/liblte_rrc.h" #include "srslte/asn1/liblte_rrc.h"
#include "upper/rrc.h" #include "upper/rrc.h"
#include <boost/assign.hpp> #include <boost/assign.hpp>
#include <upper/rrc.h>
#include "srslte/common/security.h" #include "srslte/common/security.h"
#include "srslte/common/bcd_helpers.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", 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].phy_cell.id, known_cells[i].earfcn,
known_cells[i].sib1.cell_id); 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].phy_cell.id, known_cells[i].earfcn,
known_cells[i].sib1.cell_id); known_cells[i].sib1.cell_id);
// Check that cell satisfies S criteria // Check that cell satisfies S criteria
if (phy->cell_select(known_cells[i].earfcn, known_cells[i].phy_cell)) { if (known_cells[i].in_sync) { // %% rsrp > S dbm
last_selected_cell = i; // Try to select Cell
current_cell = &known_cells[i]; if (phy->cell_select(known_cells[i].earfcn, known_cells[i].phy_cell))
return; {
} else { last_selected_cell = i;
rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", current_cell = &known_cells[i];
known_cells[i].earfcn, known_cells[i].sib1.cell_id); 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 // find if cell_id-earfcn combination already exists
for (uint32_t i = 0; i < known_cells.size(); i++) { 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) { 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]; current_cell = &known_cells[i];
rrc_log->info("Updating cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", known_cells[i].earfcn, 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); 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) // Detection of physical layer problems (5.3.11.1)
void rrc::out_of_sync() { void rrc::out_of_sync() {
current_cell->in_sync = false;
if (!mac_timers->get(t311)->is_running() && !mac_timers->get(t310)->is_running()) { if (!mac_timers->get(t311)->is_running() && !mac_timers->get(t310)->is_running()) {
n310_cnt++; n310_cnt++;
if (n310_cnt == N310) { if (n310_cnt == N310) {
@ -268,6 +275,7 @@ void rrc::out_of_sync() {
// Recovery of physical layer problems (5.3.11.2) // Recovery of physical layer problems (5.3.11.2)
void rrc::in_sync() { void rrc::in_sync() {
current_cell->in_sync = true;
if (mac_timers->get(t310)->is_running()) { if (mac_timers->get(t310)->is_running()) {
n311_cnt++; n311_cnt++;
if (n311_cnt == N311) { if (n311_cnt == N311) {
@ -1087,7 +1095,7 @@ void rrc::reset_ue() {
mac->pcch_start_rx(); mac->pcch_start_rx();
mac_timers->get(safe_reset_timer)->stop(); mac_timers->get(safe_reset_timer)->stop();
mac_timers->get(safe_reset_timer)->reset(); 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() { void rrc::rrc_connection_release() {