Compare commits

...

7 Commits

Author SHA1 Message Date
Max
f38a0c06dc Add .gitignore 2016-06-15 16:53:49 +02:00
Tom Tsou
3b093bb13b uhd: Set minimum UHD version requirement for E3XX
Create runtime version check for minimum supported UHD driver
when using USRP E3XX devices. The minimum version, 3.9.0, matches
supported version on current E3XX release images.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-05-03 19:06:56 -07:00
Tom Tsou
3f4a13f049 uhd: Make device offset check a private method
Removes extra arguments and a static call.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-05-03 19:04:00 -07:00
Tom Tsou
0fe41a583c uhd: Set default Tx sampling to 4 sps
The majority of GSM host platforms are capable of operating with
the 4x oversampled modulator, which justifies the new default
setting. The small number exceptions (e.g. Raspberry Pi) can still
use the lower complexity 1 sps modulator with the '-s 1' command
line option if required.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-05-03 15:17:39 -07:00
Tom Tsou
a5e0f1cdba uhd: Update default E3XX settings
Tune timing values after testing on UHD 003.009.002 for E3XX.
Table value for 1 sps was off by 10 samples causing improper
operation. Table value for 4 sps was shifted by 1 sample for
more accurate timing.

Also update E3XX description string detection.

Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-05-03 15:14:06 -07:00
Tom Tsou
2c650a6895 common: Add mandatory length field to UDP receive calls
Current UDP receive reads up to MAX_UDP_LENGTH bytes into the
passed in buffer, which may lead to buffer overflow if the
write buffer is of insufficient size.

Add mandatory length argument to UDP socket receive calls.

Reported-by: Simone Margaritelli <simone@zimperium.com>
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-05-02 17:37:05 -07:00
Tom Tsou
d4555f267e common: Restrict UDP binding to localhost only
Reported security vulnerability where control and data UDP
packets can be injected into the transceiver externally due
to socket binding to all interfaces using INADDR_ANY.

Existing socket interface does not allow specifying local
address; only the local port and remote address/port are
arguments.

Restrict socket bind to localhost with INADDR_LOOPBACK. If
external interfaces do need to be used, the API should be
modified to allow specifying the local socket address.

Reported-by: Simone Margaritelli <simone@zimperium.com>
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-05-02 17:35:01 -07:00
7 changed files with 168 additions and 91 deletions

56
.gitignore vendored Normal file
View File

@@ -0,0 +1,56 @@
.deps
.libs
*.o
*.lo
CommonLibs/BitVectorTest
CommonLibs/ConfigurationTest
CommonLibs/F16Test
CommonLibs/InterthreadTest
CommonLibs/LogTest
CommonLibs/Makefile
CommonLibs/Makefile.in
CommonLibs/RegexpTest
CommonLibs/SocketsTest
CommonLibs/TimevalTest
CommonLibs/URLEncodeTest
CommonLibs/VectorTest
CommonLibs/libcommon.la
GSM/Makefile
GSM/Makefile.in
GSM/libGSM.la
Makefile
Makefile.in
Transceiver52M/Makefile
Transceiver52M/Makefile.in
Transceiver52M/arm/Makefile
Transceiver52M/arm/Makefile.in
Transceiver52M/common/.dirstamp
Transceiver52M/libtransceiver.la
Transceiver52M/osmo-trx
Transceiver52M/x86/Makefile
Transceiver52M/x86/Makefile.in
Transceiver52M/x86/libarch.la
aclocal.m4
autom4te.cache/
compile
config.guess
config.h
config.h.in
config.log
config.status
config.sub
config/libtool.m4
config/ltoptions.m4
config/ltsugar.m4
config/ltversion.m4
config/lt~obsolete.m4
configure
depcomp
install-sh
libtool
ltmain.sh
missing
sqlite3/Makefile
sqlite3/Makefile.in
sqlite3/libsqlite.la
stamp-h1

View File

@@ -187,24 +187,20 @@ int DatagramSocket::send(const struct sockaddr* dest, const char * message)
return send(dest,message,length);
}
int DatagramSocket::read(char* buffer)
int DatagramSocket::read(char* buffer, size_t length)
{
socklen_t temp_len = sizeof(mSource);
int length = recvfrom(mSocketFD, (void*)buffer, MAX_UDP_LENGTH, 0,
(struct sockaddr*)&mSource,&temp_len);
if ((length==-1) && (errno!=EAGAIN)) {
socklen_t addr_len = sizeof(mSource);
int rd_length = recvfrom(mSocketFD, (void *) buffer, length, 0,
(struct sockaddr*) &mSource, &addr_len);
if ((rd_length==-1) && (errno!=EAGAIN)) {
perror("DatagramSocket::read() failed");
throw SocketError();
}
return length;
return rd_length;
}
int DatagramSocket::read(char* buffer, unsigned timeout)
int DatagramSocket::read(char* buffer, size_t length, unsigned timeout)
{
fd_set fds;
FD_ZERO(&fds);
@@ -218,7 +214,7 @@ int DatagramSocket::read(char* buffer, unsigned timeout)
throw SocketError();
}
if (sel==0) return -1;
if (FD_ISSET(mSocketFD,&fds)) return read(buffer);
if (FD_ISSET(mSocketFD,&fds)) return read(buffer, length);
return -1;
}
@@ -269,7 +265,7 @@ void UDPSocket::open(unsigned short localPort)
size_t length = sizeof(address);
bzero(&address,length);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = htons(localPort);
if (bind(mSocketFD,(struct sockaddr*)&address,length)<0) {
perror("bind() failed");

View File

@@ -108,7 +108,7 @@ public:
@param buffer A char[MAX_UDP_LENGTH] procured by the caller.
@return The number of bytes received or -1 on non-blocking pass.
*/
int read(char* buffer);
int read(char* buffer, size_t length);
/**
Receive a packet with a timeout.
@@ -116,7 +116,7 @@ public:
@param maximum wait time in milliseconds
@return The number of bytes received or -1 on timeout.
*/
int read(char* buffer, unsigned timeout);
int read(char* buffer, size_t length, unsigned timeout);
/** Send a packet to a given destination, other than the default. */

View File

@@ -42,7 +42,7 @@ void *testReaderIP(void *)
int rc = 0;
while (rc<gNumToSend) {
char buf[MAX_UDP_LENGTH];
int count = readSocket.read(buf);
int count = readSocket.read(buf, MAX_UDP_LENGTH);
if (count>0) {
COUT("read: " << buf);
rc++;
@@ -62,7 +62,7 @@ void *testReaderUnix(void *)
int rc = 0;
while (rc<gNumToSend) {
char buf[MAX_UDP_LENGTH];
int count = readSocket.read(buf);
int count = readSocket.read(buf, MAX_UDP_LENGTH);
if (count>0) {
COUT("read: " << buf);
rc++;

View File

@@ -704,7 +704,7 @@ void Transceiver::driveControl(size_t chan)
int msgLen = -1;
buffer[0] = '\0';
msgLen = mCtrlSockets[chan]->read(buffer);
msgLen = mCtrlSockets[chan]->read(buffer, sizeof(buffer));
if (msgLen < 1) {
return;
@@ -872,7 +872,7 @@ bool Transceiver::driveTxPriorityQueue(size_t chan)
char buffer[gSlotLen+50];
// check data socket
size_t msgLen = mDataSockets[chan]->read(buffer);
size_t msgLen = mDataSockets[chan]->read(buffer, sizeof(buffer));
if (msgLen!=gSlotLen+1+4+1) {
LOG(ERR) << "badly formatted packet on GSM->TRX interface";

View File

@@ -68,8 +68,8 @@ enum uhd_dev_type {
struct uhd_dev_offset {
enum uhd_dev_type type;
int tx_sps;
int rx_sps;
size_t tx_sps;
size_t rx_sps;
double offset;
const std::string desc;
};
@@ -110,8 +110,8 @@ static struct uhd_dev_offset uhd_offsets[] = {
{ B210, 4, 1, B2XX_TIMING_4SPS, "B210 4 SPS" },
{ E1XX, 1, 1, 9.5192e-5, "E1XX 1 SPS" },
{ E1XX, 4, 1, 6.5571e-5, "E1XX 4 SPS" },
{ E3XX, 1, 1, 1.5000e-4, "E3XX 1 SPS" },
{ E3XX, 4, 1, 1.2740e-4, "E3XX 4 SPS" },
{ E3XX, 1, 1, 1.84616e-4, "E3XX 1 SPS" },
{ E3XX, 4, 1, 1.29231e-4, "E3XX 4 SPS" },
{ X3XX, 1, 1, 1.5360e-4, "X3XX 1 SPS"},
{ X3XX, 4, 1, 1.1264e-4, "X3XX 4 SPS"},
{ UMTRX, 1, 1, 9.9692e-5, "UmTRX 1 SPS" },
@@ -131,63 +131,6 @@ static struct uhd_dev_offset special_offsets[] = {
{ UMTRX, 4, 1, 5.2103e-5, "UmTRX diversity, 4 SPS" },
};
static double get_dev_offset(enum uhd_dev_type type, int tx_sps, int rx_sps,
bool edge = false, bool diversity = false)
{
struct uhd_dev_offset *offset = NULL;
/* Reject USRP1 */
if (type == USRP1) {
LOG(ERR) << "Invalid device type";
return 0.0;
}
if (edge && diversity) {
LOG(ERR) << "Unsupported configuration";
return 0.0;
}
if (edge && (type != B200) && (type != B210) && (type != UMTRX)) {
LOG(ALERT) << "EDGE is supported on B200/B210 and UmTRX only";
return 0.0;
}
/* Special cases (e.g. diversity receiver) */
if (diversity) {
if (type != UMTRX) {
LOG(ALERT) << "Diversity on UmTRX only";
return 0.0;
}
switch (tx_sps) {
case 1:
offset = &special_offsets[0];
break;
case 4:
default:
offset = &special_offsets[1];
}
} else {
/* Search for matching offset value */
for (size_t i = 0; i < NUM_UHD_OFFSETS; i++) {
if ((type == uhd_offsets[i].type) &&
(tx_sps == uhd_offsets[i].tx_sps) &&
(rx_sps == uhd_offsets[i].rx_sps)) {
offset = &uhd_offsets[i];
break;
}
}
}
if (!offset) {
LOG(ERR) << "Invalid device configuration";
return 0.0;
}
std::cout << "-- Setting " << offset->desc << std::endl;
return offset->offset;
}
/*
* Select sample rate based on device type and requested samples-per-symbol.
@@ -385,6 +328,7 @@ private:
std::vector<smpl_buf *> rx_buffers;
void init_gains();
double get_dev_offset(bool edge, bool diversity);
int set_master_clk(double rate);
int set_rates(double tx_rate, double rx_rate);
bool parse_dev_type();
@@ -513,6 +457,64 @@ void uhd_device::init_gains()
}
double uhd_device::get_dev_offset(bool edge, bool diversity)
{
struct uhd_dev_offset *offset = NULL;
/* Reject USRP1 */
if (dev_type == USRP1) {
LOG(ERR) << "Invalid device type";
return 0.0;
}
if (edge && diversity) {
LOG(ERR) << "Unsupported configuration";
return 0.0;
}
if (edge && (dev_type != B200) &&
(dev_type != B210) && (dev_type != UMTRX)) {
LOG(ALERT) << "EDGE is supported on B200/B210 and UmTRX only";
return 0.0;
}
/* Special cases (e.g. diversity receiver) */
if (diversity) {
if (dev_type != UMTRX) {
LOG(ALERT) << "Diversity on UmTRX only";
return 0.0;
}
switch (tx_sps) {
case 1:
offset = &special_offsets[0];
break;
case 4:
default:
offset = &special_offsets[1];
}
} else {
/* Search for matching offset value */
for (size_t i = 0; i < NUM_UHD_OFFSETS; i++) {
if ((dev_type == uhd_offsets[i].type) &&
(tx_sps == uhd_offsets[i].tx_sps) &&
(rx_sps == uhd_offsets[i].rx_sps)) {
offset = &uhd_offsets[i];
break;
}
}
}
if (!offset) {
LOG(ERR) << "Invalid device configuration";
return 0.0;
}
std::cout << "-- Setting " << offset->desc << std::endl;
return offset->offset;
}
int uhd_device::set_master_clk(double clk_rate)
{
double actual, offset, limit = 1.0;
@@ -643,7 +645,7 @@ bool uhd_device::parse_dev_type()
{
std::string mboard_str, dev_str;
uhd::property_tree::sptr prop_tree;
size_t usrp1_str, usrp2_str, e100_str, e110_str, e310_str,
size_t usrp1_str, usrp2_str, e100_str, e110_str, e310_str, e3xx_str,
b100_str, b200_str, b210_str, x300_str, x310_str, umtrx_str;
prop_tree = usrp_dev->get_device()->get_tree();
@@ -658,6 +660,7 @@ bool uhd_device::parse_dev_type()
e100_str = mboard_str.find("E100");
e110_str = mboard_str.find("E110");
e310_str = mboard_str.find("E310");
e3xx_str = mboard_str.find("E3XX");
x300_str = mboard_str.find("X300");
x310_str = mboard_str.find("X310");
umtrx_str = dev_str.find("UmTRX");
@@ -687,7 +690,8 @@ bool uhd_device::parse_dev_type()
} else if (usrp2_str != std::string::npos) {
tx_window = TX_WINDOW_FIXED;
dev_type = USRP2;
} else if (e310_str != std::string::npos) {
} else if ((e310_str != std::string::npos) ||
(e3xx_str != std::string::npos)) {
tx_window = TX_WINDOW_FIXED;
dev_type = E3XX;
} else if (x300_str != std::string::npos) {
@@ -700,7 +704,8 @@ bool uhd_device::parse_dev_type()
tx_window = TX_WINDOW_FIXED;
dev_type = UMTRX;
} else {
LOG(ALERT) << "Unknown UHD device type " << dev_str;
LOG(ALERT) << "Unknown UHD device type "
<< dev_str << " " << mboard_str;
return false;
}
@@ -715,6 +720,26 @@ bool uhd_device::parse_dev_type()
return true;
}
/*
* Check for UHD version > 3.9.0 for E3XX support
*/
static bool uhd_e3xx_version_chk()
{
std::string ver = uhd::get_version_string();
std::string major_str(ver.begin(), ver.begin() + 3);
std::string minor_str(ver.begin() + 4, ver.begin() + 7);
int major_val = atoi(major_str.c_str());
int minor_val = atoi(minor_str.c_str());
if (major_val < 3)
return false;
if (minor_val < 9)
return false;
return true;
}
int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
{
// Find UHD devices
@@ -738,6 +763,11 @@ int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
if (!parse_dev_type())
return -1;
if ((dev_type == E3XX) && !uhd_e3xx_version_chk()) {
LOG(ALERT) << "E3XX requires UHD 003.009.000 or greater";
return -1;
}
// Verify and set channels
if ((dev_type == B210) && (chans == 2)) {
} else if ((dev_type == UMTRX) && (chans == 2)) {
@@ -801,7 +831,7 @@ int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
if (rx_sps == 4)
edge = true;
double offset = get_dev_offset(dev_type, tx_sps, rx_sps, edge, diversity);
double offset = get_dev_offset(edge, diversity);
if (offset == 0.0) {
LOG(ERR) << "Unsupported configuration, no correction applied";
ts_offset = 0;

View File

@@ -37,14 +37,9 @@
* 1 - Uses minimized modulator (less computation, more distortion)
*
* Other values are invalid. Receive path (uplink) is always
* downsampled to 1 sps. Default to 4 sps for all cases except for
* ARM and non-SIMD enabled architectures.
* downsampled to 1 sps. Default to 4 sps for all cases.
*/
#if defined(HAVE_NEON) || !defined(HAVE_SSE3)
#define DEFAULT_TX_SPS 1
#else
#define DEFAULT_TX_SPS 4
#endif
/*
* Samples-per-symbol for uplink (receiver) path