Reduced chances of uhd demuxer error. Reset device when it occurs

This commit is contained in:
Ismael Gomez 2017-09-15 17:49:31 +02:00
parent fa11ca8e41
commit 826667361e
11 changed files with 173 additions and 109 deletions

View File

@ -518,9 +518,9 @@ public:
/* Cell search and selection procedures */
virtual void cell_search_start() = 0;
virtual void cell_search_stop() = 0;
virtual void cell_search_next() = 0;
virtual bool cell_select(uint32_t earfcn, srslte_cell_t cell) = 0;
virtual bool sync_stop() = 0;
/* Is the PHY downlink synchronized? */
virtual bool sync_status() = 0;
@ -529,8 +529,6 @@ public:
virtual void configure_ul_params(bool pregen_disabled = false) = 0;
virtual void reset() = 0;
virtual void resync_sfn() = 0;
};

View File

@ -78,7 +78,8 @@ namespace srslte {
};
bool init(char *args = NULL, char *devname = NULL);
void stop();
void stop();
void reset();
bool start_agc(bool tx_gain_same_rx);
void set_burst_preamble(double preamble_us);
@ -170,6 +171,10 @@ namespace srslte {
bool agc_enabled;
int offset;
uint32_t sf_len;
char saved_args[128];
char saved_devname[128];
};
}

View File

@ -628,9 +628,11 @@ int rf_uhd_recv_with_time_multi(void *h,
} else if (error_code == UHD_RX_METADATA_ERROR_CODE_LATE_COMMAND) {
log_late(handler);
} else if (error_code == UHD_RX_METADATA_ERROR_CODE_TIMEOUT) {
fprintf(stderr, "Error timed out while receiving asynchronoous messages from UHD.\n");
fprintf(stderr, "Error timed out while receiving samples from UHD.\n");
return -1;
} else if (error_code != UHD_RX_METADATA_ERROR_CODE_NONE ) {
fprintf(stderr, "Error code 0x%x was returned during streaming. Aborting.\n", error_code);
return -1;
}
} while (n < nsamples && trials < 100);

View File

@ -297,7 +297,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q,
ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer);
if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
break;
return -1;
} else if (ret == 1) {
/* This means a peak was found and ue_sync is now in tracking state */
ret = srslte_sync_get_cell_id(&q->ue_sync.strack);

View File

@ -271,7 +271,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q,
ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer);
if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
break;
return -1;
} else if (srslte_ue_sync_get_sfidx(&q->ue_sync) == 0) {
if (ret == 1) {
mib_ret = srslte_ue_mib_decode(&q->ue_mib, q->sf_buffer[0], bch_payload, nof_tx_ports, sfn_offset);

View File

@ -30,6 +30,7 @@ extern "C" {
}
#include "srslte/radio/radio.h"
#include <string.h>
#include <unistd.h>
namespace srslte {
@ -60,7 +61,10 @@ bool radio::init(char *args, char *devname)
} else {
printf("\nWarning burst preamble is not calibrated for device %s. Set a value manually\n\n", srslte_rf_name(&rf_device));
}
strncpy(saved_args, args, 128);
strncpy(saved_devname, devname, 128);
return true;
}
@ -69,6 +73,16 @@ void radio::stop()
srslte_rf_close(&rf_device);
}
void radio::reset()
{
printf("Resetting Radio...\n");
srslte_rf_close(&rf_device);
sleep(3);
if (srslte_rf_open_devname(&rf_device, saved_devname, saved_args)) {
fprintf(stderr, "Error opening RF device\n");
}
}
void radio::set_manual_calibration(rf_cal_t* calibration)
{
srslte_rf_cal_t tx_cal;

View File

@ -52,13 +52,12 @@ public:
void stop();
void set_agc_enable(bool enable);
void resync_sfn();
void set_earfcn(std::vector<uint32_t> earfcn);
bool stop_sync();
void cell_search_start();
void cell_search_next();
void cell_search_stop();
void cell_search_next(bool reset = false);
bool cell_select(uint32_t earfcn, srslte_cell_t cell);
uint32_t get_current_tti();
@ -79,11 +78,16 @@ private:
void set_sampling_rate();
bool set_frequency();
void resync_sfn();
void cell_search_inc();
bool init_cell();
void free_cell();
bool init_cell();
void free_cell();
void stop_rx();
void start_rx();
bool radio_is_rx;
bool running;
@ -153,7 +157,7 @@ private:
int cell_sync_sfn();
int cell_meas_rsrp();
bool cell_search(int force_N_id_2 = -1);
int cell_search(int force_N_id_2 = -1);
bool set_cell();
};

View File

@ -80,18 +80,17 @@ public:
/********** RRC INTERFACE ********************/
void reset();
void configure_ul_params(bool pregen_disabled = false);
void resync_sfn();
void cell_search_start();
void cell_search_stop();
void cell_search_next();
bool cell_select(uint32_t earfcn, srslte_cell_t phy_cell);
/********** MAC INTERFACE ********************/
/* Functions to synchronize with a cell */
bool sync_status(); // this is also RRC interface
bool sync_stop();
/* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */
void set_crnti(uint16_t rnti);
void set_crnti(uint16_t rnti);
/* Instructs the PHY to configure using the parameters written by set_param() */
void configure_prach_params();

View File

@ -41,6 +41,7 @@ namespace srsue {
int radio_recv_wrapper_cs(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time) {
srslte::radio_multi *radio_h = (srslte::radio_multi *) h;
if (radio_h->rx_now(data, nsamples, rx_time)) {
int offset = nsamples - radio_h->get_tti_len();
if (abs(offset) < 10 && offset != 0) {
@ -226,7 +227,7 @@ bool phch_recv::set_cell() {
return cell_is_set;
}
bool phch_recv::cell_search(int force_N_id_2) {
int phch_recv::cell_search(int force_N_id_2) {
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
srslte_ue_cellsearch_result_t found_cells[3];
@ -238,7 +239,7 @@ bool phch_recv::cell_search(int force_N_id_2) {
srate_mode = SRATE_FIND;
radio_h->set_rx_srate(1.92e6);
}
radio_h->start_rx();
start_rx();
/* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */
uint32_t max_peak_cell = 0;
@ -257,13 +258,12 @@ bool phch_recv::cell_search(int force_N_id_2) {
last_gain = srslte_agc_get_gain(&cs.ue_sync.agc);
if (ret < 0) {
radio_h->stop_rx();
Error("SYNC: Error decoding MIB: Error searching PSS\n");
return false;
return -1;
} else if (ret == 0) {
radio_h->stop_rx();
stop_rx();
Info("SYNC: Could not find any cell in this frequency\n");
return false;
return 0;
}
// Save result
cell.id = found_cells[max_peak_cell].cell_id;
@ -294,7 +294,7 @@ bool phch_recv::cell_search(int force_N_id_2) {
ret = srslte_ue_mib_sync_decode(&ue_mib_sync,
40,
bch_payload, &cell.nof_ports, &sfn_offset);
radio_h->stop_rx();
stop_rx();
last_gain = srslte_agc_get_gain(&ue_mib_sync.ue_sync.agc);
cellsearch_cfo = srslte_ue_sync_get_cfo(&ue_mib_sync.ue_sync);
@ -311,9 +311,12 @@ bool phch_recv::cell_search(int force_N_id_2) {
cell.id, cell.nof_prb, cell.nof_ports, cellsearch_cfo/1000);
return true;
} else {
} else if (ret == 0) {
Warning("SYNC: Found PSS but could not decode PBCH\n");
return false;
return 0;
} else {
Error("SYNC: Receiving MIB\n");
return -1;
}
}
@ -391,8 +394,8 @@ int phch_recv::cell_meas_rsrp() {
}
void phch_recv::resync_sfn() {
radio_h->stop_rx();
radio_h->start_rx();
stop_rx();
start_rx();
srslte_ue_mib_reset(&ue_mib);
Info("SYNC: Starting SFN synchronization\n");
sync_sfn_cnt = 0;
@ -417,24 +420,28 @@ bool phch_recv::stop_sync() {
void phch_recv::cell_search_inc()
{
cur_earfcn_index++;
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size() - 1) {
cur_earfcn_index = 0;
}
}
usleep(100000);
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
if (current_earfcn != earfcn[cur_earfcn_index]) {
current_earfcn = earfcn[cur_earfcn_index];
set_frequency();
}
}
void phch_recv::cell_search_next() {
if (cell_search_in_progress) {
void phch_recv::cell_search_next(bool reset) {
if (cell_search_in_progress || reset) {
cell_search_in_progress = false;
if (!stop_sync()) {
log_h->warning("SYNC: Couldn't stop PHY\n");
}
if (reset) {
cur_earfcn_index = -1;
}
cell_search_inc();
phy_state = CELL_SEARCH;
cell_search_in_progress = true;
@ -443,16 +450,22 @@ void phch_recv::cell_search_next() {
void phch_recv::cell_search_start() {
if (earfcn.size() > 0) {
cell_search_in_progress = true;
cur_earfcn_index = -1;
cell_search_next();
log_h->info("SYNC: Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
Info("SYNC: Starting Cell Search procedure in %d EARFCNs...\n", earfcn.size());
cell_search_next(true);
} else {
log_h->info("SYNC: Empty EARFCN list. Stopping cell search...\n");
Info("SYNC: Empty EARFCN list. Stopping cell search...\n");
log_h->console("Empty EARFCN list. Stopping cell search...\n");
}
}
void phch_recv::cell_search_stop() {
Info("SYNC: Stopping Cell Search procedure...\n");
if (!stop_sync()) {
Error("SYNC: Stopping cell search\n");
}
cell_search_in_progress = false;
}
bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
// Check if we are already camping in this cell
@ -476,6 +489,8 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
current_earfcn = earfcn;
printf("cell select called set frequency\n");
if (set_frequency()) {
this->cell = cell;
log_h->info("Cell Select: Configuring cell...\n");
@ -536,7 +551,6 @@ void phch_recv::set_sampling_rate()
}
void phch_recv::run_thread() {
int sync_res;
phch_worker *worker = NULL;
cf_t *buffer[SRSLTE_MAX_PORTS];
phy_state = IDLE;
@ -549,20 +563,28 @@ void phch_recv::run_thread() {
}
switch (phy_state) {
case CELL_SEARCH:
if (cell_search() && cell_search_in_progress) {
if (!srslte_cell_isvalid(&cell)) {
Error("SYNC: Detected invalid cell\n");
phy_state = IDLE;
if (cell_search_in_progress) {
switch(cell_search()) {
case 1:
if (!srslte_cell_isvalid(&cell)) {
Error("SYNC: Detected invalid cell\n");
phy_state = IDLE;
break;
}
if (set_cell()) {
set_sampling_rate();
resync_sfn();
}
break;
}
if (set_cell()) {
set_sampling_rate();
resync_sfn();
}
} else {
if (cell_search_in_progress) {
cell_search_inc();
case 0:
if (cell_search_in_progress) {
cell_search_inc();
}
break;
default:
log_h->error("SYNC: Receiving frorm radio.\n");
phy_state = IDLE;
radio_h->reset();
}
}
break;
@ -571,10 +593,6 @@ void phch_recv::run_thread() {
srslte_ue_sync_decode_sss_on_track(&ue_sync, true);
switch (cell_sync_sfn()) {
default:
log_h->console("SYNC: Going IDLE\n");
phy_state = IDLE;
break;
case 1:
srslte_ue_sync_set_agc_period(&ue_sync, 20);
if (!cell_search_in_progress) {
@ -588,6 +606,11 @@ void phch_recv::run_thread() {
break;
case 0:
break;
default:
log_h->error("SYNC: Receiving frorm radio.\n");
phy_state = IDLE;
radio_h->reset();
break;
}
sync_sfn_cnt++;
if (sync_sfn_cnt >= SYNC_SFN_TIMEOUT) {
@ -604,10 +627,13 @@ void phch_recv::run_thread() {
rrc->cell_found(earfcn[cur_earfcn_index], cell, 10*log10(measure_rsrp/1000));
break;
case 0:
break;
default:
log_h->error("SYNC: Getting RSRP cell measurement.\n");
cell_search_next();
break;
default:
log_h->error("SYNC: Receiving frorm radio.\n");
phy_state = IDLE;
radio_h->reset();
}
break;
case CELL_CAMP:
@ -618,53 +644,57 @@ void phch_recv::run_thread() {
buffer[i] = worker->get_buffer(i);
}
sync_res = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer);
if (sync_res == 1) {
switch(srslte_ue_sync_zerocopy_multi(&ue_sync, buffer)) {
case 1:
log_h->step(tti);
log_h->step(tti);
Debug("SYNC: Worker %d synchronized\n", worker->get_id());
Debug("SYNC: Worker %d synchronized\n", worker->get_id());
metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync);
metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync);
worker->set_cfo(ul_dl_factor * metrics.cfo / 15000);
worker_com->set_sync_metrics(metrics);
metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync);
metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync);
worker->set_cfo(ul_dl_factor * metrics.cfo / 15000);
worker_com->set_sync_metrics(metrics);
float sample_offset = (float) srslte_ue_sync_get_sfo(&ue_sync) / 1000;
worker->set_sample_offset(sample_offset);
worker->set_sample_offset(srslte_ue_sync_get_sfo(&ue_sync)/1000);
/* Compute TX time: Any transmission happens in TTI4 thus advance 4 ms the reception time */
srslte_timestamp_t rx_time, tx_time, tx_time_prach;
srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time);
srslte_timestamp_copy(&tx_time, &rx_time);
srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec);
worker->set_tx_time(tx_time);
/* Compute TX time: Any transmission happens in TTI4 thus advance 4 ms the reception time */
srslte_timestamp_t rx_time, tx_time, tx_time_prach;
srslte_ue_sync_get_last_timestamp(&ue_sync, &rx_time);
srslte_timestamp_copy(&tx_time, &rx_time);
srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec);
worker->set_tx_time(tx_time);
Debug("SYNC: Setting TTI=%d, tx_mutex=%d to worker %d\n", tti, tx_mutex_cnt, worker->get_id());
worker->set_tti(tti, tx_mutex_cnt);
tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex;
Debug("SYNC: Setting TTI=%d, tx_mutex=%d to worker %d\n", tti, tx_mutex_cnt, worker->get_id());
worker->set_tti(tti, tx_mutex_cnt);
tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex;
// Check if we need to TX a PRACH
if (prach_buffer->is_ready_to_send(tti)) {
srslte_timestamp_copy(&tx_time_prach, &rx_time);
srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3);
prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach);
radio_h->tx_end();
worker_com->p0_preamble = prach_buffer->get_p0_preamble();
worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble);
}
workers_pool->start_worker(worker);
// Notify RRC in-sync every 1 frame
if ((tti % 10) == 0) {
rrc->in_sync();
log_h->debug("SYNC: Sending in-sync to RRC\n");
}
} else {
log_h->error("SYNC: Sync error. Sending out-of-sync to RRC\n");
// Notify RRC of out-of-sync frame
rrc->out_of_sync();
worker->release();
worker_com->reset_ul();
// Check if we need to TX a PRACH
if (prach_buffer->is_ready_to_send(tti)) {
srslte_timestamp_copy(&tx_time_prach, &rx_time);
srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3);
prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach);
radio_h->tx_end();
worker_com->p0_preamble = prach_buffer->get_p0_preamble();
worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble);
}
workers_pool->start_worker(worker);
// Notify RRC in-sync every 1 frame
if ((tti % 10) == 0) {
rrc->in_sync();
log_h->debug("SYNC: Sending in-sync to RRC\n");
}
case 0:
log_h->error("SYNC: Sync error. Sending out-of-sync to RRC\n");
// Notify RRC of out-of-sync frame
rrc->out_of_sync();
worker->release();
worker_com->reset_ul();
break;
default:
log_h->error("SYNC: Receiving frorm radio.\n");
phy_state = IDLE;
radio_h->reset();
}
} else {
// wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here
@ -673,7 +703,7 @@ void phch_recv::run_thread() {
break;
case IDLE:
if (!is_in_idle) {
radio_h->stop_rx();
stop_rx();
}
is_in_idle = true;
usleep(1000);
@ -682,6 +712,22 @@ void phch_recv::run_thread() {
}
}
void phch_recv::stop_rx() {
if (radio_is_rx) {
Info("SYNC: Stopping RX streaming\n");
radio_h->stop_rx();
}
radio_is_rx = false;
}
void phch_recv::start_rx() {
if (!radio_is_rx) {
Info("SYNC: Starting RX streaming\n");
radio_h->start_rx();
}
radio_is_rx = true;
}
uint32_t phch_recv::get_current_tti() {
return tti;
}

View File

@ -232,6 +232,11 @@ void phy::cell_search_start()
sf_recv.cell_search_start();
}
void phy::cell_search_stop()
{
sf_recv.cell_search_stop();
}
void phy::cell_search_next()
{
sf_recv.cell_search_next();
@ -293,7 +298,7 @@ int phy::prach_tx_tti()
void phy::reset()
{
// TODO
sf_recv.stop_sync();
n_ta = 0;
pdcch_dl_search_reset();
for(uint32_t i=0;i<nof_workers;i++) {
@ -317,10 +322,6 @@ int phy::sr_last_tx_tti()
return workers_common.sr_last_tx_tti;
}
void phy::resync_sfn() {
sf_recv.resync_sfn();
}
void phy::set_earfcn(vector< uint32_t > earfcns)
{
sf_recv.set_earfcn(earfcns);
@ -331,11 +332,6 @@ bool phy::sync_status()
return sf_recv.status_is_sync();
}
bool phy::sync_stop()
{
return sf_recv.stop_sync();
}
void phy::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN])
{
workers_common.set_rar_grant(tti, grant_payload);

View File

@ -430,6 +430,7 @@ void rrc::run_thread() {
plmn_select_timeout++;
if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) {
rrc_log->info("RRC PLMN Search: timeout expired. Searching again\n");
phy->cell_search_stop();
sleep(1);
rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n");
plmn_select_timeout = 0;
@ -714,7 +715,6 @@ void rrc::send_con_restablish_request() {
mac->reset();
// FIXME: Cell selection should be different??
phy->resync_sfn();
// Wait for cell re-synchronization
uint32_t timeout_cnt = 0;
@ -1097,7 +1097,7 @@ void rrc::rrc_connection_release() {
pthread_mutex_lock(&mutex);
drb_up = false;
state = RRC_STATE_IDLE;
phy->sync_stop();
phy->reset();
set_phy_default();
set_mac_default();
mac_timers->get(t311)->run();