Added proper error handling

master
ismagom 9 years ago
parent b7520aa792
commit 2fa0c76e5c

@ -48,7 +48,18 @@ typedef struct {
float tx_rx_gain_offset; float tx_rx_gain_offset;
} srslte_rf_t; } 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, SRSLTE_API int srslte_rf_open(srslte_rf_t *h,
char *args); 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_suppress_stdout(srslte_rf_t *h);
SRSLTE_API void srslte_rf_register_msg_handler(srslte_rf_t *h, SRSLTE_API void srslte_rf_register_error_handler(srslte_rf_t *h,
srslte_rf_msg_handler_t msg_handler); srslte_rf_error_handler_t error_handler);
SRSLTE_API double srslte_rf_set_rx_freq(srslte_rf_t *h, SRSLTE_API double srslte_rf_set_rx_freq(srslte_rf_t *h,
double freq); double freq);

@ -47,15 +47,17 @@ typedef struct {
bool tx_stream_enabled; bool tx_stream_enabled;
} rf_blade_handler_t; } rf_blade_handler_t;
srslte_rf_error_handler_t blade_error_handler = NULL;
void rf_blade_suppress_stdout(void *h) { void rf_blade_suppress_stdout(void *h) {
bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_SILENT); 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) bool rf_blade_rx_wait_lo_locked(void *h)
{ {
usleep(1000); 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); status = bladerf_sync_rx(handler->dev, handler->rx_buffer, nsamples, &meta, 0);
if (status) { if (status) {
fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status)); fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status));
exit(-1);
return -1; return -1;
} else if (meta.status & BLADERF_META_STATUS_OVERRUN) { } 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); "%u valid samples were read.\n\n", meta.actual_count);
}
} }
timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs); 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; meta.flags |= BLADERF_META_FLAG_TX_BURST_END;
} }
status = bladerf_sync_tx(handler->dev, handler->tx_buffer, nsamples, &meta, 0); 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)); fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status));
return 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; return nsamples;
} }

@ -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_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, SRSLTE_API double rf_blade_set_rx_freq(void *h,
double freq); double freq);

@ -35,7 +35,7 @@ typedef struct {
bool (*srslte_rf_has_rssi)(void *h); bool (*srslte_rf_has_rssi)(void *h);
float (*srslte_rf_get_rssi)(void *h); float (*srslte_rf_get_rssi)(void *h);
void (*srslte_rf_suppress_stdout)(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_open)(char *args, void **h);
int (*srslte_rf_close)(void *h); int (*srslte_rf_close)(void *h);
void (*srslte_rf_set_master_clock_rate)(void *h, double rate); 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_has_rssi,
rf_uhd_get_rssi, rf_uhd_get_rssi,
rf_uhd_suppress_stdout, rf_uhd_suppress_stdout,
rf_uhd_register_msg_handler, rf_uhd_register_error_handler,
rf_uhd_open, rf_uhd_open,
rf_uhd_close, rf_uhd_close,
rf_uhd_set_master_clock_rate, rf_uhd_set_master_clock_rate,
@ -103,7 +103,7 @@ static rf_dev_t dev_blade = {
rf_blade_has_rssi, rf_blade_has_rssi,
rf_blade_get_rssi, rf_blade_get_rssi,
rf_blade_suppress_stdout, rf_blade_suppress_stdout,
rf_blade_register_msg_handler, rf_blade_register_error_handler,
rf_blade_open, rf_blade_open,
rf_blade_close, rf_blade_close,
rf_blade_set_master_clock_rate, rf_blade_set_master_clock_rate,

@ -161,9 +161,9 @@ void srslte_rf_suppress_stdout(srslte_rf_t *rf)
((rf_dev_t*) rf->dev)->srslte_rf_suppress_stdout(rf->handler); ((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) int srslte_rf_open(srslte_rf_t *h, char *args)

@ -55,13 +55,33 @@ void suppress_handler(const char *x)
// do nothing // do nothing
} }
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_suppress_stdout(void *h) { void rf_uhd_suppress_stdout(void *h) {
rf_uhd_register_msg_handler(h, suppress_handler); rf_uhd_register_msg_handler_c(suppress_handler);
} }
void rf_uhd_register_msg_handler(void *notused, srslte_rf_msg_handler_t new_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) static bool find_string(uhd_string_vector_handle h, char *str)

@ -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_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, SRSLTE_API double rf_uhd_set_rx_freq(void *h,
double freq); double freq);

@ -9,17 +9,17 @@ extern "C" {
#include "uhd_c_api.h" #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) void translate_handler(uhd::msg::type_t type, const std::string & msg)
{ {
if(msg_handler) if(handler)
msg_handler(msg.c_str()); 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); uhd::msg::register_handler(translate_handler);
} }

@ -4,7 +4,7 @@
#include "srslte/rf/rf.h" #include "srslte/rf/rf.h"
/* Declare functions not currently provided by the C-API */ /* 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_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_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); SRSLTE_API void uhd_tx_metadata_set_end(uhd_tx_metadata_handle *md, bool is_end_of_burst);

Loading…
Cancel
Save