[PATCH] osmo-trx[master]: Add support to set Rx/TxAntenna

Pau Espin Pedrol gerrit-no-reply at lists.osmocom.org
Mon Feb 5 14:09:33 UTC 2018


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/6238

to look at the new patch set (#2).

Add support to set Rx/TxAntenna

Change-Id: I1735e6ab05a05b0312d6d679b16ebd4a2260fa23
---
M Transceiver52M/UHDDevice.cpp
M Transceiver52M/USRPDevice.cpp
M Transceiver52M/USRPDevice.h
M Transceiver52M/osmo-trx.cpp
M Transceiver52M/radioDevice.h
5 files changed, 253 insertions(+), 10 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/38/6238/2

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 @@
 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 @@
 	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 @@
 
 	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 @@
 	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 @@
 }
 
 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 @@
 	this->chans = chans;
 	this->offset = offset;
 	this->iface = iface;
+	this->tx_paths = tx_paths;
+	this->rx_paths = rx_paths;
 }
 
 uhd_device::~uhd_device()
@@ -439,6 +452,33 @@
 
 	ts_offset = static_cast<TIMESTAMP>(desc.offset * rx_rate);
 	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)
@@ -641,6 +681,11 @@
 		set_channels(swap_channels);
         } catch (const std::exception &e) {
 		LOG(ALERT) << "Channel setting failed - " << e.what();
+		return -1;
+	}
+
+	if (!set_antennas()) {
+		LOG(ALERT) << "UHD antenna setting failed";
 		return -1;
 	}
 
@@ -1165,6 +1210,78 @@
 	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 @@
 }
 
 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 @@
   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 @@
 #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 @@
   /** 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 @@
 	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 @@
 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 @@
 	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 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 @@
 		"  -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 @@
 	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 @@
 		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);
@@ -388,6 +431,19 @@
 
 	if (config->rach_delay > 68) {
 		printf("RACH delay is too big %i\n\n", config->rach_delay);
+		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;
 	}
 
@@ -480,7 +536,7 @@
 		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 @@
   };
 
   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 @@
   /** 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;

-- 
To view, visit https://gerrit.osmocom.org/6238
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I1735e6ab05a05b0312d6d679b16ebd4a2260fa23
Gerrit-PatchSet: 2
Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de>
Gerrit-Reviewer: Vadim Yanitskiy <axilirator at gmail.com>


More information about the gerrit-log mailing list