Add support to set Rx/TxAntenna

Change-Id: I1735e6ab05a05b0312d6d679b16ebd4a2260fa23
This commit is contained in:
Pau Espin 2018-02-05 13:05:06 +01:00
parent f58cd8ac83
commit 8d9071229e
5 changed files with 253 additions and 10 deletions

View File

@ -208,7 +208,9 @@ private:
class uhd_device : public RadioDevice {
public:
uhd_device(size_t tx_sps, size_t rx_sps, InterfaceType type,
size_t chans, double offset);
size_t chans, double offset,
const std::vector<std::string>& tx_paths,
const std::vector<std::string>& rx_paths);
~uhd_device();
int open(const std::string &args, int ref, bool swap_channels);
@ -248,6 +250,11 @@ public:
double getRxFreq(size_t chan);
double getRxFreq();
bool setRxAntenna(const std::string &ant, size_t chan);
std::string getRxAntenna(size_t chan);
bool setTxAntenna(const std::string &ant, size_t chan);
std::string getTxAntenna(size_t chan);
inline double getSampleRate() { return tx_rate; }
inline double numberRead() { return rx_pkt_cnt; }
inline double numberWritten() { return 0; }
@ -280,6 +287,7 @@ private:
std::vector<double> tx_gains, rx_gains;
std::vector<double> tx_freqs, rx_freqs;
std::vector<std::string> tx_paths, rx_paths;
size_t tx_spp, rx_spp;
bool started;
@ -295,6 +303,7 @@ private:
void init_gains();
void set_channels(bool swap);
void set_rates();
bool set_antennas();
bool parse_dev_type();
bool flush_recv(size_t num_pkts);
int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);
@ -353,7 +362,9 @@ static void thread_enable_cancel(bool cancel)
}
uhd_device::uhd_device(size_t tx_sps, size_t rx_sps,
InterfaceType iface, size_t chans, double offset)
InterfaceType iface, size_t chans, double offset,
const std::vector<std::string>& tx_paths,
const std::vector<std::string>& rx_paths)
: tx_gain_min(0.0), tx_gain_max(0.0),
rx_gain_min(0.0), rx_gain_max(0.0),
tx_spp(0), rx_spp(0),
@ -365,6 +376,8 @@ uhd_device::uhd_device(size_t tx_sps, size_t rx_sps,
this->chans = chans;
this->offset = offset;
this->iface = iface;
this->tx_paths = tx_paths;
this->rx_paths = rx_paths;
}
uhd_device::~uhd_device()
@ -441,6 +454,33 @@ void uhd_device::set_rates()
LOG(INFO) << "Rates configured for " << desc.str;
}
bool uhd_device::set_antennas()
{
unsigned int i;
for (i = 0; i < tx_paths.size(); i++) {
if (tx_paths[i] == "")
continue;
LOG(DEBUG) << "Configuring channel " << i << " with antenna " << tx_paths[i];
if (!setTxAntenna(tx_paths[i], i)) {
LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << tx_paths[i];
return false;
}
}
for (i = 0; i < rx_paths.size(); i++) {
if (rx_paths[i] == "")
continue;
LOG(DEBUG) << "Configuring channel " << i << " with antenna " << rx_paths[i];
if (!setRxAntenna(rx_paths[i], i)) {
LOG(ALERT) << "Failed configuring channel " << i << " with antenna " << rx_paths[i];
return false;
}
}
LOG(INFO) << "Antennas configured successfully";
return true;
}
double uhd_device::setTxGain(double db, size_t chan)
{
if (iface == MULTI_ARFCN)
@ -644,6 +684,11 @@ int uhd_device::open(const std::string &args, int ref, bool swap_channels)
return -1;
}
if (!set_antennas()) {
LOG(ALERT) << "UHD antenna setting failed";
return -1;
}
tx_freqs.resize(chans);
rx_freqs.resize(chans);
tx_gains.resize(chans);
@ -1165,6 +1210,78 @@ double uhd_device::getRxFreq(size_t chan)
return rx_freqs[chan];
}
bool uhd_device::setRxAntenna(const std::string &ant, size_t chan)
{
std::vector<std::string> avail;
if (chan >= rx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return false;
}
avail = usrp_dev->get_rx_antennas(chan);
if (std::find(avail.begin(), avail.end(), ant) == avail.end()) {
LOG(ALERT) << "Requested non-existent Rx antenna " << ant << " on channel " << chan;
LOG(INFO) << "Available Rx antennas: ";
for (std::vector<std::string>::const_iterator i = avail.begin(); i != avail.end(); ++i)
LOG(INFO) << "- '" << *i << "'";
return false;
}
usrp_dev->set_rx_antenna(ant, chan);
rx_paths[chan] = usrp_dev->get_rx_antenna(chan);
if (ant != rx_paths[chan]) {
LOG(ALERT) << "Failed setting antenna " << ant << " on channel " << chan << ", got instead " << rx_paths[chan];
return false;
}
return true;
}
std::string uhd_device::getRxAntenna(size_t chan)
{
if (chan >= rx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return "";
}
return usrp_dev->get_rx_antenna(chan);
}
bool uhd_device::setTxAntenna(const std::string &ant, size_t chan)
{
std::vector<std::string> avail;
if (chan >= tx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return false;
}
avail = usrp_dev->get_tx_antennas(chan);
if (std::find(avail.begin(), avail.end(), ant) == avail.end()) {
LOG(ALERT) << "Requested non-existent Tx antenna " << ant << " on channel " << chan;
LOG(INFO) << "Available Tx antennas: ";
for (std::vector<std::string>::const_iterator i = avail.begin(); i != avail.end(); ++i)
LOG(INFO) << "- '" << *i << "'";
return false;
}
usrp_dev->set_tx_antenna(ant, chan);
tx_paths[chan] = usrp_dev->get_tx_antenna(chan);
if (ant != tx_paths[chan]) {
LOG(ALERT) << "Failed setting antenna " << ant << " on channel " << chan << ", got instead " << tx_paths[chan];
return false;
}
return true;
}
std::string uhd_device::getTxAntenna(size_t chan)
{
if (chan >= tx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return "";
}
return usrp_dev->get_tx_antenna(chan);
}
/*
* Only allow sampling the Rx path lower than Tx and not vice-versa.
* Using Tx with 4 SPS and Rx at 1 SPS is the only allowed mixed
@ -1451,7 +1568,9 @@ std::string smpl_buf::str_code(ssize_t code)
}
RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps,
InterfaceType iface, size_t chans, double offset)
InterfaceType iface, size_t chans, double offset,
const std::vector<std::string>& tx_paths,
const std::vector<std::string>& rx_paths)
{
return new uhd_device(tx_sps, rx_sps, iface, chans, offset);
return new uhd_device(tx_sps, rx_sps, iface, chans, offset, tx_paths, rx_paths);
}

View File

@ -313,6 +313,46 @@ double USRPDevice::setRxGain(double dB, size_t chan)
return dB;
}
bool USRPDevice::setRxAntenna(const std::string &ant, size_t chan)
{
if (chan >= rx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return false;
}
LOG(ALERT) << "Not implemented";
return true;
}
std::string USRPDevice::getRxAntenna(size_t chan)
{
if (chan >= rx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return "";
}
LOG(ALERT) << "Not implemented";
return "";
}
bool USRPDevice::setTxAntenna(const std::string &ant, size_t chan)
{
if (chan >= tx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return false;
}
LOG(ALERT) << "Not implemented";
return true;
}
std::string USRPDevice::getTxAntenna(size_t chan)
{
if (chan >= tx_paths.size()) {
LOG(ALERT) << "Requested non-existent channel " << chan;
return "";
}
LOG(ALERT) << "Not implemented";
return "";
}
// NOTE: Assumes sequential reads
int USRPDevice::readSamples(std::vector<short *> &bufs, int len, bool *overrun,
@ -600,7 +640,9 @@ bool USRPDevice::setRxFreq(double wFreq) { return true;};
#endif
RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps,
RadioDevice::InterfaceType, size_t chans, double)
InterfaceType iface, size_t chans, double offset,
const std::vector<std::string>& tx_paths,
const std::vector<std::string>& rx_paths)
{
return new USRPDevice(tx_sps);
}

View File

@ -179,6 +179,18 @@ private:
/** return minimum Rx Gain **/
double minTxGain(void);
/** sets the RX path to use, returns true if successful and false otherwise */
bool setRxAntenna(const std::string &ant, size_t chan = 0);
/* return the used RX path */
std::string getRxAntenna(size_t chan = 0);
/** sets the RX path to use, returns true if successful and false otherwise */
bool setTxAntenna(const std::string &ant, size_t chan = 0);
/* return the used RX path */
std::string getTxAntenna(size_t chan = 0);
/** Return internal status values */
inline double getTxFreq(size_t chan = 0) { return 0; }
inline double getRxFreq(size_t chan = 0) { return 0; }

View File

@ -28,6 +28,10 @@
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <GSMCommon.h>
#include <Logger.h>
@ -79,6 +83,8 @@ struct trx_config {
bool swap_channels;
bool edge;
int sched_rr;
std::vector<std::string> rx_paths;
std::vector<std::string> tx_paths;
};
volatile bool gshutdown = false;
@ -93,6 +99,7 @@ volatile bool gshutdown = false;
bool trx_setup_config(struct trx_config *config)
{
std::string refstr, fillstr, divstr, mcstr, edgestr;
std::vector<std::string>::const_iterator si;
if (config->mcbts && config->chans > 5) {
std::cout << "Unsupported number of channels" << std::endl;
@ -144,8 +151,16 @@ bool trx_setup_config(struct trx_config *config)
ost << " Tuning offset........... " << config->offset << std::endl;
ost << " RSSI to dBm offset...... " << config->rssi_offset << std::endl;
ost << " Swap channels........... " << config->swap_channels << std::endl;
std::cout << ost << std::endl;
ost << " Tx Antennas.............";
for (si = config->tx_paths.begin(); si != config->tx_paths.end(); ++si)
ost << " '" << ((*si != "") ? *si : "<default>") << "'";
ost << std::endl;
ost << " Rx Antennas.............";
for (si = config->rx_paths.begin(); si != config->rx_paths.end(); ++si)
ost << " '" << ((*si != "") ? *si : "<default>") << "'";
ost << std::endl;
std::cout << ost << std::endl;
return true;
}
@ -241,6 +256,21 @@ static void setup_signal_handlers()
}
}
static std::vector<std::string> comma_delimited_to_vector(char* opt) {
std::string str = std::string(opt);
std::vector<std::string> result;
std::stringstream ss(str);
while( ss.good() )
{
std::string substr;
getline(ss, substr, ',');
result.push_back(substr);
}
return result;
}
static void print_help()
{
fprintf(stdout, "Options:\n"
@ -263,13 +293,16 @@ static void print_help()
" -A Random Access Burst test mode with delay\n"
" -R RSSI to dBm offset in dB (default=0)\n"
" -S Swap channels (UmTRX only)\n"
" -t SCHED_RR real-time priority (1..32)\n",
" -t SCHED_RR real-time priority (1..32)\n"
" -y comma-delimited list of Tx paths (num elements matches -c)\n"
" -z comma-delimited list of Rx paths (num elements matches -c)\n",
"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
}
static void handle_options(int argc, char **argv, struct trx_config *config)
{
int option;
bool tx_path_set = false, rx_path_set = false;
config->log_level = "NOTICE";
config->local_addr = DEFAULT_TRX_IP;
@ -289,8 +322,10 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
config->swap_channels = false;
config->edge = false;
config->sched_rr = -1;
config->tx_paths = std::vector<std::string>(DEFAULT_CHANS, "");
config->rx_paths = std::vector<std::string>(DEFAULT_CHANS, "");
while ((option = getopt(argc, argv, "ha:l:i:j:p:c:dmxgfo:s:b:r:A:R:Set:")) != -1) {
while ((option = getopt(argc, argv, "ha:l:i:j:p:c:dmxgfo:s:b:r:A:R:Set:y:z:")) != -1) {
switch (option) {
case 'h':
print_help();
@ -355,6 +390,14 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
case 't':
config->sched_rr = atoi(optarg);
break;
case 'y':
config->tx_paths = comma_delimited_to_vector(optarg);
tx_path_set = true;
break;
case 'z':
config->rx_paths = comma_delimited_to_vector(optarg);
rx_path_set = true;
break;
default:
print_help();
exit(0);
@ -391,6 +434,19 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
goto bad_config;
}
if (!tx_path_set) {
config->tx_paths = std::vector<std::string>(config->chans, "");
} else if (config->tx_paths.size() != config->chans) {
printf("Num of channels and num of Tx Antennas doesn't match\n\n");
goto bad_config;
}
if (!rx_path_set) {
config->rx_paths = std::vector<std::string>(config->chans, "");
} else if (config->rx_paths.size() != config->chans) {
printf("Num of channels and num of Rx Antennas doesn't match\n\n");
goto bad_config;
}
return;
bad_config:
@ -480,7 +536,7 @@ int main(int argc, char *argv[])
ref = RadioDevice::REF_INTERNAL;
usrp = RadioDevice::make(config.tx_sps, config.rx_sps, iface,
config.chans, config.offset);
config.chans, config.offset, config.tx_paths, config.rx_paths);
type = usrp->open(config.dev_args, ref, config.swap_channels);
if (type < 0) {
LOG(ALERT) << "Failed to create radio device" << std::endl;

View File

@ -50,7 +50,9 @@ class RadioDevice {
};
static RadioDevice *make(size_t tx_sps, size_t rx_sps, InterfaceType type,
size_t chans = 1, double offset = 0.0);
size_t chans = 1, double offset = 0.0,
const std::vector<std::string>& tx_paths = std::vector<std::string>(1, ""),
const std::vector<std::string>& rx_paths = std::vector<std::string>(1, ""));
/** Initialize the USRP */
virtual int open(const std::string &args, int ref, bool swap_channels)=0;
@ -136,6 +138,18 @@ class RadioDevice {
/** return minimum Tx Gain **/
virtual double minTxGain(void) = 0;
/** sets the RX path to use, returns true if successful and false otherwise */
virtual bool setRxAntenna(const std::string &ant, size_t chan = 0) = 0;
/** return the used RX path */
virtual std::string getRxAntenna(size_t chan = 0) = 0;
/** sets the RX path to use, returns true if successful and false otherwise */
virtual bool setTxAntenna(const std::string &ant, size_t chan = 0) = 0;
/** return the used RX path */
virtual std::string getTxAntenna(size_t chan = 0) = 0;
/** Return internal status values */
virtual double getTxFreq(size_t chan = 0) = 0;
virtual double getRxFreq(size_t chan = 0) = 0;