Compare commits

..

1 Commits

Author SHA1 Message Date
Ivan Kluchnikov
3605872e43 Transceiver52M: UHD: Exit on receive more than 100 timeout errors
Receiving timeout is not a fatal error and should be recoverable on network devices.
But for some reasons these errors are not always recoverable, in this case osmo-trx should be restarted.
2014-06-30 20:36:51 +04:00
13 changed files with 22 additions and 230 deletions

View File

@@ -192,7 +192,7 @@ Log::~Log()
if (mDummyInit) return;
// Anything at or above LOG_CRIT is an "alarm".
// Save alarms in the local list and echo them to stderr.
if (mPriority <= LOG_ERR) {
if (mPriority <= LOG_CRIT) {
if (sLoggerInited) addAlarm(mStream.str().c_str());
cerr << mStream.str() << endl;
}

View File

@@ -91,8 +91,7 @@ Transceiver::Transceiver(int wBasePort,
: mBasePort(wBasePort), mAddr(TRXAddress),
mTransmitLatency(wTransmitLatency), mClockSocket(NULL),
mRadioInterface(wRadioInterface), mSPSTx(wSPS), mSPSRx(1), mChans(wChans),
mOn(false), mTxFreq(0.0), mRxFreq(0.0), mPower(-10), mMaxExpectedDelay(0),
mTSC(0)
mOn(false), mTxFreq(0.0), mRxFreq(0.0), mPower(-10), mMaxExpectedDelay(0)
{
GSM::Time startTime(random() % gHyperframe,0);
@@ -106,12 +105,6 @@ Transceiver::Transceiver(int wBasePort,
txFullScale = mRadioInterface->fullScaleInputValue();
rxFullScale = mRadioInterface->fullScaleOutputValue();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++)
mHandover[i][j] = false;
}
}
Transceiver::~Transceiver()
@@ -303,12 +296,6 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
size_t chan)
{
TransceiverState *state = &mStates[chan];
static int tchh_subslot[26] = { 0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,1 };
static int sdcch4_subslot[102] = { 3,3,3,3,0,0,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2,
3,3,3,3,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2 };
static int sdcch8_subslot[102] = { 5,5,5,5,6,6,6,6,7,7,7,7,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,0,0,0,0,
1,1,1,1,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,4,4,4,4 };
unsigned burstTN = currTime.TN();
unsigned burstFN = currTime.FN();
@@ -320,8 +307,6 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
return IDLE;
break;
case I:
if (mHandover[burstTN][0])
return RACH;
return TSC;
/*if (burstFN % 26 == 25)
return IDLE;
@@ -332,8 +317,6 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
return TSC;
break;
case III:
if (mHandover[burstTN][tchh_subslot[burstFN % 26]])
return RACH;
return TSC;
break;
case IV:
@@ -348,8 +331,6 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
return RACH;
else if ((mod51 == 45) || (mod51 == 46))
return RACH;
else if (mHandover[burstTN][sdcch4_subslot[burstFN % 102]])
return RACH;
else
return TSC;
break;
@@ -357,8 +338,6 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
case VII:
if ((burstFN % 51 <= 14) && (burstFN % 51 >= 12))
return IDLE;
else if (mHandover[burstTN][sdcch8_subslot[burstFN % 102]])
return RACH;
else
return TSC;
break;
@@ -524,18 +503,10 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
else
success = detectRACH(state, *burst, amp, toa);
if (success == 0) {
if (!success) {
state->mNoises.insert(avg);
delete radio_burst;
return NULL;
} else if (success < 0) {
if (success == -SIGERR_CLIP) {
LOG(ALERT) << "Clipping detected on RACH input";
} else {
LOG(ALERT) << "Unhandled RACH error";
}
delete radio_burst;
return NULL;
}
/* Demodulate and set output info */
@@ -612,10 +583,6 @@ void Transceiver::driveControl(size_t chan)
sprintf(response,"RSP POWERON 1");
else {
sprintf(response,"RSP POWERON 0");
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++)
mHandover[i][j] = false;
}
if (!chan && !mOn) {
// Prepare for thread start
mPower = -20;
@@ -642,20 +609,6 @@ void Transceiver::driveControl(size_t chan)
}
}
}
else if (strcmp(command,"HANDOVER")==0){
int ts=0,ss=0;
sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&ts,&ss);
mHandover[ts][ss] = true;
LOG(WARNING) << "HANDOVER RACH at timeslot " << ts << " subslot " << ss;
sprintf(response,"RSP HANDOVER 0 %d %d",ts,ss);
}
else if (strcmp(command,"NOHANDOVER")==0){
int ts=0,ss=0;
sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&ts,&ss);
mHandover[ts][ss] = false;
LOG(WARNING) << "NOHANDOVER at timeslot " << ts << " subslot " << ss;
sprintf(response,"RSP NOHANDOVER 0 %d %d",ts,ss);
}
else if (strcmp(command,"SETMAXDLY")==0) {
//set expected maximum time-of-arrival
int maxDelay;
@@ -732,7 +685,7 @@ void Transceiver::driveControl(size_t chan)
// set TSC
unsigned TSC;
sscanf(buffer, "%3s %s %d", cmdcheck, command, &TSC);
if (mOn || (TSC<0) || (TSC>7))
if (mOn)
sprintf(response, "RSP SETTSC 1 %d", TSC);
else if (chan && (TSC != mTSC))
sprintf(response, "RSP SETTSC 1 %d", TSC);
@@ -743,7 +696,7 @@ void Transceiver::driveControl(size_t chan)
}
}
else if (strcmp(command,"SETSLOT")==0) {
// set slot type
// set TSC
int corrCode;
int timeslot;
sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&timeslot,&corrCode);
@@ -759,7 +712,6 @@ void Transceiver::driveControl(size_t chan)
}
else {
LOG(WARNING) << "bogus command " << command << " on control interface.";
sprintf(response,"RSP ERR 1");
}
mCtrlSockets[chan]->write(response, strlen(response) + 1);

View File

@@ -163,7 +163,6 @@ private:
size_t mChans;
bool mOn; ///< flag to indicate that transceiver is powered on
bool mHandover[8][8]; ///< expect handover to the timeslot/subslot
double mTxFreq; ///< the transmit frequency
double mRxFreq; ///< the receive frequency
int mPower; ///< the transmit power in dB

View File

@@ -37,12 +37,9 @@
#define B2XX_BASE_RT GSMRATE
#define B100_BASE_RT 400000
#define USRP2_BASE_RT 390625
#define USRP_TX_AMPL 0.3
#define UMTRX_TX_AMPL 0.7
#define TX_AMPL 0.3
#define SAMPLE_BUF_SZ (1 << 20)
#define UMTRX_VGA1_DEF -18
enum uhd_dev_type {
USRP1,
USRP2,
@@ -289,7 +286,7 @@ public:
inline TIMESTAMP initialWriteTimestamp() { return ts_initial * sps; }
inline TIMESTAMP initialReadTimestamp() { return ts_initial; }
inline double fullScaleInputValue() { return (dev_type==UMTRX) ? (32000 * UMTRX_TX_AMPL) : (32000 * USRP_TX_AMPL); }
inline double fullScaleInputValue() { return 32000 * TX_AMPL; }
inline double fullScaleOutputValue() { return 32000; }
double setRxGain(double db, size_t chan);
@@ -424,43 +421,21 @@ void uhd_device::init_gains()
{
uhd::gain_range_t range;
if (dev_type == UMTRX) {
std::vector<std::string> gain_stages = usrp_dev->get_tx_gain_names(0);
if (gain_stages[0] == "VGA") {
LOG(WARNING) << "Update your UHD version for a proper Tx gain support";
}
if (gain_stages[0] == "VGA" || gain_stages[0] == "PA") {
range = usrp_dev->get_tx_gain_range();
tx_gain_min = range.start();
tx_gain_max = range.stop();
} else {
range = usrp_dev->get_tx_gain_range("VGA2");
tx_gain_min = UMTRX_VGA1_DEF + range.start();
tx_gain_max = UMTRX_VGA1_DEF + range.stop();
}
} else {
range = usrp_dev->get_tx_gain_range();
tx_gain_min = range.start();
tx_gain_max = range.stop();
}
LOG(INFO) << "Supported Tx gain range [" << tx_gain_min << "; " << tx_gain_max << "]";
range = usrp_dev->get_rx_gain_range();
rx_gain_min = range.start();
rx_gain_max = range.stop();
LOG(INFO) << "Supported Rx gain range [" << rx_gain_min << "; " << rx_gain_max << "]";
for (size_t i = 0; i < tx_gains.size(); i++) {
double gain = (tx_gain_min + tx_gain_max) / 2;
LOG(INFO) << "Default setting Tx gain for channel " << i << " to " << gain;
usrp_dev->set_tx_gain(gain, i);
usrp_dev->set_tx_gain((tx_gain_min + tx_gain_max) / 2, i);
tx_gains[i] = usrp_dev->get_tx_gain(i);
}
for (size_t i = 0; i < rx_gains.size(); i++) {
double gain = (rx_gain_min + rx_gain_max) / 2;
LOG(INFO) << "Default setting Rx gain for channel " << i << " to " << gain;
usrp_dev->set_rx_gain(gain, i);
usrp_dev->set_rx_gain((rx_gain_min + rx_gain_max) / 2, i);
rx_gains[i] = usrp_dev->get_rx_gain(i);
}
@@ -539,27 +514,10 @@ double uhd_device::setTxGain(double db, size_t chan)
return 0.0f;
}
if (dev_type == UMTRX) {
std::vector<std::string> gain_stages = usrp_dev->get_tx_gain_names(0);
if (gain_stages[0] == "VGA" || gain_stages[0] == "PA") {
usrp_dev->set_tx_gain(db, chan);
tx_gains[chan] = usrp_dev->get_tx_gain(chan);
} else {
// New UHD versions support split configuration of
// Tx gain stages. We utilize this to set the gain
// configuration, optimal for the Tx signal quality.
// From our measurements, VGA1 must be 18dB plus-minus
// one and VGA2 is the best when 23dB or lower.
usrp_dev->set_tx_gain(UMTRX_VGA1_DEF, "VGA1", chan);
usrp_dev->set_tx_gain(db-UMTRX_VGA1_DEF, "VGA2", chan);
tx_gains[chan] = usrp_dev->get_tx_gain(chan);
}
} else {
usrp_dev->set_tx_gain(db, chan);
tx_gains[chan] = usrp_dev->get_tx_gain(chan);
}
LOG(INFO) << "Set TX gain to " << tx_gains[chan] << "dB (asked for " << db << "dB)";
LOG(INFO) << "Set TX gain to " << tx_gains[chan] << "dB";
return tx_gains[chan];
}
@@ -574,7 +532,7 @@ double uhd_device::setRxGain(double db, size_t chan)
usrp_dev->set_rx_gain(db, chan);
rx_gains[chan] = usrp_dev->get_rx_gain(chan);
LOG(INFO) << "Set RX gain to " << rx_gains[chan] << "dB (asked for " << db << "dB)";
LOG(INFO) << "Set RX gain to " << rx_gains[chan] << "dB";
return rx_gains[chan];
}
@@ -672,7 +630,7 @@ int uhd_device::open(const std::string &args, bool extref)
// Use the first found device
LOG(INFO) << "Using discovered UHD device " << dev_addrs[0].to_string();
try {
usrp_dev = uhd::usrp::multi_usrp::make(addr);
usrp_dev = uhd::usrp::multi_usrp::make(dev_addrs[0]);
} catch(...) {
LOG(ALERT) << "UHD make failed, device " << dev_addrs[0].to_string();
return -1;
@@ -715,16 +673,6 @@ int uhd_device::open(const std::string &args, bool extref)
if (set_rates(_tx_rate, _rx_rate) < 0)
return -1;
// Set RF frontend bandwidth
if (dev_type == UMTRX) {
// Setting LMS6002D LPF to 500kHz gives us the best signal quality
for (size_t i = 0; i < chans; i++) {
usrp_dev->set_tx_bandwidth(500*1000*2, i);
if (!diversity)
usrp_dev->set_rx_bandwidth(500*1000*2, i);
}
}
/* Create TX and RX streamers */
uhd::stream_args_t stream_args("sc16");
for (size_t i = 0; i < chans; i++)
@@ -1065,19 +1013,7 @@ uhd::tune_request_t uhd_device::select_freq(double freq, size_t chan, bool tx)
std::vector<double> freqs;
uhd::tune_request_t treq(freq);
if (dev_type == UMTRX) {
if (offset > 0.0)
return uhd::tune_request_t(freq, offset);
// Don't use DSP tuning, because LMS6002D PLL steps are small enough.
// We end up with DSP tuning just for 2-3Hz, which is meaningless and
// only distort the signal (because cordic is not ideal).
treq.target_freq = freq;
treq.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
treq.rf_freq = freq;
treq.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
treq.dsp_freq = 0.0;
} else if (chans == 1) {
if ((chans == 1) || ((chans == 2) && dev_type == UMTRX)) {
if (offset == 0.0)
return treq;

View File

@@ -34,8 +34,6 @@ extern "C" {
#include "scale.h"
#include "mult.h"
}
/* Clipping detection threshold */
#define CLIP_THRESH 30000.0f
using namespace GSM;
@@ -1342,7 +1340,7 @@ static int detectBurst(signalVector &burst,
/* Correlate */
if (!convolve(&burst, sync->sequence, &corr,
CUSTOM, start, len, sps, 0)) {
return -SIGERR_INTERNAL;
return -1;
}
/* Peak detection - place restrictions at correlation edges */
@@ -1371,18 +1369,6 @@ static int detectBurst(signalVector &burst,
return 1;
}
static int detectClipping(signalVector &burst, float thresh)
{
for (size_t i = 0; i < burst.size(); i++) {
if (fabs(burst[i].real()) > thresh)
return 1;
if (fabs(burst[i].imag()) > thresh)
return 1;
}
return 0;
}
/*
* RACH burst detection
*
@@ -1404,10 +1390,7 @@ int detectRACHBurst(signalVector &rxBurst,
CorrelationSequence *sync;
if ((sps != 1) && (sps != 4))
return -SIGERR_UNSUPPORTED;
if (detectClipping(rxBurst, CLIP_THRESH))
return -SIGERR_CLIP;
return -1;
target = 8 + 40;
head = 4;
@@ -1460,7 +1443,7 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
CorrelationSequence *sync;
if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
return -SIGERR_UNSUPPORTED;
return -1;
target = 3 + 58 + 16 + 5;
head = 4;
@@ -1476,7 +1459,7 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
delete corr;
if (rc < 0) {
return -SIGERR_INTERNAL;
return -1;
} else if (!rc) {
if (amp)
*amp = 0.0f;

View File

@@ -28,14 +28,6 @@ enum ConvType {
UNDEFINED,
};
enum signalError {
SIGERR_NONE,
SIGERR_BOUNDS,
SIGERR_CLIP,
SIGERR_UNSUPPORTED,
SIGERR_INTERNAL,
};
/** Convert a linear number to a dB value */
float dB(float x);

5
debian/changelog vendored
View File

@@ -1,5 +0,0 @@
osmo-trx (0.1.8) precise; urgency=low
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP
-- Ivan Klyuchnikov <Ivan.Kluchnikov@fairwaves.ru> Sun, 9 Mar 2014 14:10:10 +0400

1
debian/compat vendored
View File

@@ -1 +0,0 @@
9

24
debian/control vendored
View File

@@ -1,24 +0,0 @@
Source: osmo-trx
Maintainer: Ivan Klyuchnikov <ivan.kluchnikov@fairwaves.ru>
Section: net
Priority: optional
Standards-Version: 3.9.3
Build-Depends: debhelper (>= 9), autotools-dev, libdbd-sqlite3, pkg-config, dh-autoreconf, uhd, umtrx-uhd, libusb-1.0-0-dev, libboost-all-dev
Homepage: http://openbsc.osmocom.org/trac/wiki/OsmoTRX
Vcs-Git: git://git.osmocom.org/osmo-trx
Vcs-Browser: http://cgit.osmocom.org/osmo-trx
Package: osmo-trx
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
Description: OsmoTRX is a software-defined radio transceiver that implements the Layer 1 physical layer of a BTS
Package: osmo-trx-dbg
Architecture: any
Section: debug
Priority: extra
Depends: osmo-trx (= ${binary:Version}), ${misc:Depends}
Description: Debug symbols for the osmo-trx
Make debugging possible

25
debian/copyright vendored
View File

@@ -1,25 +0,0 @@
The Debian packaging is:
Copyright (C) 2014 Max <max.suraev@fairwaves.ru>
It was downloaded from:
git://git.osmocom.org/osmo-trx
Upstream Authors:
Thomas Tsou <tom@tsou.cc>
David A. Burgess <dburgess@kestrelsp.com>
Harvind S. Samra <hssamra@kestrelsp.com>
Raffi Sevlian <raffisev@gmail.com>
Copyright:
Copyright (C) 2012-2013 Thomas Tsou <tom@tsou.cc>
Copyright (C) 2011 Range Networks, Inc.
Copyright (C) 2008-2011 Free Software Foundation, Inc.
License:
GNU Affero General Public License, Version 3

View File

@@ -1 +0,0 @@
/usr/bin/osmo-trx

13
debian/rules vendored
View File

@@ -1,13 +0,0 @@
#!/usr/bin/make -f
export DEB_BUILD_HARDENING=1
%:
dh $@ --with autoreconf
override_dh_shlibdeps:
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
override_dh_strip:
dh_strip --dbg-package=osmo-trx-dbg

View File

@@ -1 +0,0 @@
3.0 (native)