diff options
-rw-r--r-- | Transceiver52M/UHDDevice.cpp | 127 | ||||
-rw-r--r-- | Transceiver52M/USRPDevice.cpp | 44 | ||||
-rw-r--r-- | Transceiver52M/USRPDevice.h | 12 | ||||
-rw-r--r-- | Transceiver52M/osmo-trx.cpp | 64 | ||||
-rw-r--r-- | Transceiver52M/radioDevice.h | 16 |
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; |