Added proper error handling

This commit is contained in:
ismagom 2015-12-18 12:38:25 +01:00
parent b7520aa792
commit 2fa0c76e5c
9 changed files with 82 additions and 25 deletions

View File

@ -48,7 +48,18 @@ typedef struct {
float tx_rx_gain_offset;
} srslte_rf_t;
typedef void (*srslte_rf_msg_handler_t)(const char*);
typedef struct {
enum {
SRSLTE_RF_ERROR_LATE,
SRSLTE_RF_ERROR_UNDERFLOW,
SRSLTE_RF_ERROR_OVERFLOW,
SRSLTE_RF_ERROR_OTHER
} type;
int opt;
const char *msg;
} srslte_rf_error_t;
typedef void (*srslte_rf_error_handler_t)(srslte_rf_error_t error);
SRSLTE_API int srslte_rf_open(srslte_rf_t *h,
char *args);
@ -97,8 +108,8 @@ SRSLTE_API double srslte_rf_get_tx_gain(srslte_rf_t *h);
SRSLTE_API void srslte_rf_suppress_stdout(srslte_rf_t *h);
SRSLTE_API void srslte_rf_register_msg_handler(srslte_rf_t *h,
srslte_rf_msg_handler_t msg_handler);
SRSLTE_API void srslte_rf_register_error_handler(srslte_rf_t *h,
srslte_rf_error_handler_t error_handler);
SRSLTE_API double srslte_rf_set_rx_freq(srslte_rf_t *h,
double freq);

View File

@ -47,15 +47,17 @@ typedef struct {
bool tx_stream_enabled;
} rf_blade_handler_t;
srslte_rf_error_handler_t blade_error_handler = NULL;
void rf_blade_suppress_stdout(void *h) {
bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_SILENT);
}
void rf_blade_register_msg_handler(void *notused, srslte_rf_msg_handler_t new_handler)
void rf_blade_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler)
{
new_handler = blade_error_handler;
}
bool rf_blade_rx_wait_lo_locked(void *h)
{
usleep(1000);
@ -403,11 +405,17 @@ int rf_blade_recv_with_time(void *h,
status = bladerf_sync_rx(handler->dev, handler->rx_buffer, nsamples, &meta, 0);
if (status) {
fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status));
exit(-1);
return -1;
} else if (meta.status & BLADERF_META_STATUS_OVERRUN) {
fprintf(stderr, "Overrun detected in scheduled RX. "
if (blade_error_handler) {
srslte_rf_error_t error;
error.opt = meta.actual_count;
error.type = SRSLTE_RF_ERROR_OVERFLOW;
blade_error_handler(error);
} else {
fprintf(stderr, "Overrun detected in scheduled RX. "
"%u valid samples were read.\n\n", meta.actual_count);
}
}
timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs);
@ -454,10 +462,27 @@ int rf_blade_send_timed(void *h,
meta.flags |= BLADERF_META_FLAG_TX_BURST_END;
}
status = bladerf_sync_tx(handler->dev, handler->tx_buffer, nsamples, &meta, 0);
if (status != 0) {
if (status == BLADERF_ERR_TIME_PAST) {
if (blade_error_handler) {
srslte_rf_error_t error;
error.type = SRSLTE_RF_ERROR_LATE;
blade_error_handler(error);
} else {
fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status));
}
} else if (status) {
fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status));
return status;
} else if (meta.status == BLADERF_META_STATUS_UNDERRUN) {
if (blade_error_handler) {
srslte_rf_error_t error;
error.type = SRSLTE_RF_ERROR_UNDERFLOW;
blade_error_handler(error);
} else {
fprintf(stderr, "TX warning: underflow detected.\n");
}
}
return nsamples;
}

View File

@ -67,7 +67,8 @@ SRSLTE_API double rf_blade_get_tx_gain(void *h);
SRSLTE_API void rf_blade_suppress_stdout(void *h);
SRSLTE_API void rf_blade_register_msg_handler(void *h, srslte_rf_msg_handler_t msg_handler);
SRSLTE_API void rf_blade_register_error_handler(void *h,
srslte_rf_error_handler_t error_handler);
SRSLTE_API double rf_blade_set_rx_freq(void *h,
double freq);

View File

@ -35,7 +35,7 @@ typedef struct {
bool (*srslte_rf_has_rssi)(void *h);
float (*srslte_rf_get_rssi)(void *h);
void (*srslte_rf_suppress_stdout)(void *h);
void (*srslte_rf_register_msg_handler)(void *h, srslte_rf_msg_handler_t msg_handler);
void (*srslte_rf_register_error_handler)(void *h, srslte_rf_error_handler_t error_handler);
int (*srslte_rf_open)(char *args, void **h);
int (*srslte_rf_close)(void *h);
void (*srslte_rf_set_master_clock_rate)(void *h, double rate);
@ -70,7 +70,7 @@ static rf_dev_t dev_uhd = {
rf_uhd_has_rssi,
rf_uhd_get_rssi,
rf_uhd_suppress_stdout,
rf_uhd_register_msg_handler,
rf_uhd_register_error_handler,
rf_uhd_open,
rf_uhd_close,
rf_uhd_set_master_clock_rate,
@ -103,7 +103,7 @@ static rf_dev_t dev_blade = {
rf_blade_has_rssi,
rf_blade_get_rssi,
rf_blade_suppress_stdout,
rf_blade_register_msg_handler,
rf_blade_register_error_handler,
rf_blade_open,
rf_blade_close,
rf_blade_set_master_clock_rate,

View File

@ -161,9 +161,9 @@ void srslte_rf_suppress_stdout(srslte_rf_t *rf)
((rf_dev_t*) rf->dev)->srslte_rf_suppress_stdout(rf->handler);
}
void srslte_rf_register_msg_handler(srslte_rf_t *rf, srslte_rf_msg_handler_t msg_handler)
void srslte_rf_register_error_handler(srslte_rf_t *rf, srslte_rf_error_handler_t error_handler)
{
((rf_dev_t*) rf->dev)->srslte_rf_register_msg_handler(rf->handler, msg_handler);
((rf_dev_t*) rf->dev)->srslte_rf_register_error_handler(rf->handler, error_handler);
}
int srslte_rf_open(srslte_rf_t *h, char *args)

View File

@ -55,13 +55,33 @@ void suppress_handler(const char *x)
// do nothing
}
void rf_uhd_suppress_stdout(void *h) {
rf_uhd_register_msg_handler(h, suppress_handler);
srslte_rf_error_handler_t uhd_error_handler = NULL;
void msg_handler(const char *msg)
{
srslte_rf_error_t error;
if(0 == strcmp(msg, "O")) {
error.type = SRSLTE_RF_ERROR_OVERFLOW;
} else if(0 == strcmp(msg, "D")) {
error.type = SRSLTE_RF_ERROR_OVERFLOW;
}else if(0 == strcmp(msg, "U")) {
error.type = SRSLTE_RF_ERROR_UNDERFLOW;
} else if(0 == strcmp(msg, "L")) {
error.type = SRSLTE_RF_ERROR_LATE;
}
if (uhd_error_handler) {
uhd_error_handler(error);
}
}
void rf_uhd_register_msg_handler(void *notused, srslte_rf_msg_handler_t new_handler)
void rf_uhd_suppress_stdout(void *h) {
rf_uhd_register_msg_handler_c(suppress_handler);
}
void rf_uhd_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler)
{
rf_uhd_register_msg_handler_c(new_handler);
uhd_error_handler = new_handler;
rf_uhd_register_msg_handler_c(msg_handler);
}
static bool find_string(uhd_string_vector_handle h, char *str)

View File

@ -67,7 +67,7 @@ SRSLTE_API double rf_uhd_get_tx_gain(void *h);
SRSLTE_API void rf_uhd_suppress_stdout(void *h);
SRSLTE_API void rf_uhd_register_msg_handler(void *h, srslte_rf_msg_handler_t msg_handler);
SRSLTE_API void rf_uhd_register_error_handler(void *h, srslte_rf_error_handler_t error_handler);
SRSLTE_API double rf_uhd_set_rx_freq(void *h,
double freq);

View File

@ -9,17 +9,17 @@ extern "C" {
#include "uhd_c_api.h"
}
static srslte_rf_msg_handler_t msg_handler;
static void (*handler)(const char*);
void translate_handler(uhd::msg::type_t type, const std::string & msg)
{
if(msg_handler)
msg_handler(msg.c_str());
if(handler)
handler(msg.c_str());
}
void rf_uhd_register_msg_handler_c(srslte_rf_msg_handler_t new_handler)
void rf_uhd_register_msg_handler_c(void (*new_handler)(const char*))
{
msg_handler = new_handler;
handler = new_handler;
uhd::msg::register_handler(translate_handler);
}

View File

@ -4,7 +4,7 @@
#include "srslte/rf/rf.h"
/* Declare functions not currently provided by the C-API */
SRSLTE_API void rf_uhd_register_msg_handler_c(srslte_rf_msg_handler_t new_handler);
SRSLTE_API void rf_uhd_register_msg_handler_c(void (*new_handler)(const char*));
SRSLTE_API void uhd_tx_metadata_set_time_spec(uhd_tx_metadata_handle *md, time_t secs, double frac_secs);
SRSLTE_API void uhd_tx_metadata_set_start(uhd_tx_metadata_handle *md, bool is_start_of_burst);
SRSLTE_API void uhd_tx_metadata_set_end(uhd_tx_metadata_handle *md, bool is_end_of_burst);