aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Transceiver52M/UHDDevice.cpp127
-rw-r--r--Transceiver52M/USRPDevice.cpp44
-rw-r--r--Transceiver52M/USRPDevice.h12
-rw-r--r--Transceiver52M/osmo-trx.cpp64
-rw-r--r--Transceiver52M/radioDevice.h16
5 files changed, 253 insertions, 10 deletions
diff --git a/Transceiver52M/UHDDevice.cpp b/Transceiver52M/UHDDevice.cpp
index 1120299..1687a60 100644
--- a/Transceiver52M/UHDDevice.cpp
+++ b/Transceiver52M/UHDDevice.cpp
@@ -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);
}
diff --git a/Transceiver52M/USRPDevice.cpp b/Transceiver52M/USRPDevice.cpp
index 162bb24..f7f24e9 100644
--- a/Transceiver52M/USRPDevice.cpp
+++ b/Transceiver52M/USRPDevice.cpp
@@ -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);
}
diff --git a/Transceiver52M/USRPDevice.h b/Transceiver52M/USRPDevice.h
index 3cbf672..f5fbe85 100644
--- a/Transceiver52M/USRPDevice.h
+++ b/Transceiver52M/USRPDevice.h
@@ -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; }
diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp
index 44da638..8c34893 100644
--- a/Transceiver52M/osmo-trx.cpp
+++ b/Transceiver52M/osmo-trx.cpp
@@ -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;
diff --git a/Transceiver52M/radioDevice.h b/Transceiver52M/radioDevice.h
index 3624c58..dfa1c78 100644
--- a/Transceiver52M/radioDevice.h
+++ b/Transceiver52M/radioDevice.h
@@ -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;