Compare commits

...

30 Commits

Author SHA1 Message Date
Kirill Zakharenko
b54d46e670 Bumped version to 0.1.9~1 2015-07-23 02:25:25 +02:00
Kirill Zakharenko
8c490f5f0b debian: correct dependency on libuhd, throw away dependency on umtrx-uhd 2015-07-23 02:16:58 +02:00
Kirill Zakharenko
835841853f debian: compile for atom arch with SSE3 optimizations 2015-07-18 01:28:50 +02:00
Kirill Zakharenko
e7c25a3677 transceiver/x86: don’t use -march=native to build x86 specialized code
when this option is used, it is impossible to cross-compile for x86
 variants like atom.
2015-07-18 01:27:03 +02:00
Kirill Zakharenko
6d17a6a7e6 debian: whitespace changes, more correct hardening stanza 2015-07-18 01:25:23 +02:00
Kirill Zakharenko
bb8d46adaa bumped version to 0.1.9 2015-07-16 16:45:36 +02:00
Kirill Zakharenko
20b388973c build with instruction set/tuning for atom processors
fix non-working hardening
2015-07-16 16:45:04 +02:00
Ivan Kluchnikov
0d039e2676 debian: make it possible to install osmo-trx dependencies manually on the system 2015-07-16 14:12:01 +03:00
Ivan Kluchnikov
ad669513d2 debian: update osmo-trx dependencies
Now we use uhd and umtrx-uhd instead of libuhd-dev.
2015-07-16 14:11:27 +03:00
Ivan Kluchnikov
fd978b28bd debian: Add debug package for the osmo-trx 2015-07-16 14:10:39 +03:00
Ivan Kluchnikov
1b6aaae3fa debian: Add debian directory to ease building packages 2015-07-16 14:09:55 +03:00
Alexander Chemeris
facdadc254 uhd: Output Rx/Tx gain limits to log to make it more transparent.
Conflicts:

	Transceiver52M/UHDDevice.cpp
2015-06-22 11:57:38 +03:00
Alexander Chemeris
eefa8e58f7 Logger: Output ERR log messages to stderr as well. 2015-06-22 11:40:34 +03:00
Alexander Chemeris
3ac1cbf40e Transceiver: Add support for OsmoBTS style handover. 2015-06-20 01:38:47 +03:00
Alexander Chemeris
139c84564c Transceiver: Fix whitespace. 2015-06-20 01:37:54 +03:00
Alexander Chemeris
2cb6070e09 uhd: Fix UmTRX tuning broken in commit 90f7a01d.
Commit 90f7a01d lost "return" statement. We also should account the fact that
offset can be negative.
We should return the tuning request immediately after
2015-06-20 00:05:51 +03:00
Alexander Chemeris
f2bdd1a24c transceiver: Add a debug option to dump selected timeslots to disk. 2015-06-12 00:15:31 -04:00
Alexander Chemeris
34e5a3807f Transceiver: Do not update state->SNRestimate if equalization is disabled.
This also fix a bug of using bool type for noise instead of float.
2015-06-10 23:13:33 -04:00
Alexander Chemeris
b49874aa64 uhd: Fix rounding error in timestamp conversion functions.
Rounding error introduced oscilating timing advance error by regularly
overwriting one bit and then skipping one bit.

This commit also adds an error message to show up in logs if this ever
happens again.
2015-06-10 23:13:33 -04:00
Alexander Chemeris
030951695c sigProcLib: Abstract out common part of Normal/RACH burst detection.
As a side change - get rid of passing toa and amp arguments as pointers and use
references instead.

The commit doesn't change behaviour, but makes the code cleaner.
2015-06-10 23:13:33 -04:00
Alexander Chemeris
b721d6104d Checking in clockdump.sh utility. 2015-06-10 23:03:00 -04:00
Alexander Chemeris
c19d1f6c36 Checking in a more relevant README.
This READMY is from the OpenBTS's TRXManager and actually describes the transceiver
API and behavior.
2015-06-10 23:03:00 -04:00
Alexander Chemeris
f0d8a581b4 Transceiver: Update noise level only when the timeslot is marked as IDLE.
We can't rely on an assumption that if we can't decode a burst - it's noise.
There are many rasons why we can't decode a burst even if it's well above the
noise level. Just one example is a RACH burst which can be overlapped with
another RACH burst up to a level both are completely unrecognizable. Another
example is when a burst is destroyed by bad multi-path.
2015-06-10 23:03:00 -04:00
Alexander Chemeris
37b445d4c8 transceiver: Remove noise/RSSI gating.
It does more harm than good. the current noise calculation is too error
prone, so we can't trust it. And we end up loosing perfectly good bursts
because of that.
2015-06-07 01:10:11 -04:00
Alexander Chemeris
df127bc74e osmo-trx: Add an option to swap channels on UmTRX. 2015-06-07 01:07:45 -04:00
Alexander Chemeris
6512812e43 sigProcLib: Check for bogus TOA before using it. 2015-06-05 23:40:27 -04:00
Alexander Chemeris
ded68da44f Transceiver: Fix clipping detection.
There are two primary changes in this commit:

1) Return values of detect functions changed form bool to int to actually pass
the return value from the inner function and notify higher levels about clipping.
Previously the information was lost due to conversion to bool.

2) Clipping level is not the final verdict now. We still try to demod a burst
and mark it as clipped only if the level is above the clipping level AND we can't
demod it. The reasoning for this is that in real life we want to do as much as
possible to demod the burst, because we want to get as much from our dynamic
range as possible. So a little bit of clipping is fine and is expected. We just
don't want too much of it to break our demod.
2015-06-05 23:32:41 -04:00
Alexander Chemeris
37bbfa2125 Transceiver: Print noise level for each burst in debug mode. 2015-06-05 23:25:22 -04:00
Alexander Chemeris
fdbf914584 osmo-trx: Add a command line option for the dBFS to dBm offset. 2015-06-04 19:13:48 -04:00
Alexander Chemeris
bbef7e4d70 Common: Use a scoped lock in the Logger to avoid deadlock on thread cancel. 2015-06-04 19:13:48 -04:00
20 changed files with 508 additions and 338 deletions

View File

@@ -193,7 +193,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_CRIT) {
if (mPriority <= LOG_ERR) {
if (sLoggerInited) addAlarm(mStream.str().c_str());
cerr << mStream.str() << endl;
}
@@ -206,7 +206,7 @@ Log::~Log()
if (gLogToConsole||gLogToFile) {
int mlen = mStream.str().size();
int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
gLogToLock.lock();
ScopedLock lock(gLogToLock);
if (gLogToConsole) {
// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
// so just use std::cout.
@@ -218,7 +218,6 @@ Log::~Log()
if (neednl) {fputc('\n',gLogToFile);}
fflush(gLogToFile);
}
gLogToLock.unlock();
}
}

260
README
View File

@@ -1,168 +1,116 @@
Welcome to the OpenBTS source code.
This is the interface to the transcevier.
For free support, please subscribe to openbts-discuss@lists.sourceforge.net.
See http://sourceforge.net/mailarchive/forum.php?forum_name=openbts-discuss
and https://lists.sourceforge.net/lists/listinfo/openbts-discuss for details.
For additional information, refer to http://openbts.org.
These are the directories:
AsteriskConfig Asterisk configuration files for use with OpenBTS.
CommonLib Common-use libraries, mostly C++ wrappers for basic facilities.
Control Control-layer functions for the protocols of GSM 04.08 and SIP.
GSM The GSM stack.
SIP Components of the SIP state machines ued by the control layer.
SMS The SMS stack.
SR The subscriber registry.
TRXManager The interface between the GSM stack and the radio.
Transceiver The software transceiver and specific installation tests.
apps OpenBTS application binaries.
doc Project documentation.
tests Test fixtures for subsets of OpenBTS components.
smqueue RFC-3428 store-and-forward server for SMS
Each TRX Manager UDP socket interface represents a single ARFCN.
Each of these per-ARFCN interfaces is a pair of UDP sockets, one for control and one for data.
Give a base port B (5700), the master clock interface is at port P=B.
The TRX-side control interface for C(N) is on port P=B+2N+1 and the data interface is on an odd numbered port P=B+2N+2.
The corresponding core-side interface for every socket is at P+100.
For any given build, the number of ARFCN interfaces can be fixed.
By default, OpenBTS assumes the following UDP port assignments:
Indications on the Master Clock Interface
5060 -- Asterisk SIP interface
5061 -- local SIP softphone
5062 -- OpenBTS SIP interface
5063 -- smqueue SIP interface
5064 -- subscriber registry SIP interface
5700-range -- OpenBTS-transceiver interface
The master clock interface is output only (from the radio).
Messages are "indications".
These can be controlled in the CONFIG table in /etc/OpenBTS.db.
CLOCK gives the current value of the transceiver clock to be used by the core.
This message is sent whenever a trasmission packet arrives that is too late or too early. The clock value is NOT the current transceiver time. It is a time setting the the core should use to give better packet arrival times.
IND CLOCK <totalFrames>
Standrd paths:
/OpenBTS -- Binary installation.
/etc/OpenBTS -- Configuration databases.
/var/run/OpenBTS -- Real-time reporting databases.
The script apps/setUpFiles.sh will create these directories and install the
correct files in them.
Commands on the Per-ARFCN Control Interface
The per-ARFCN control interface uses a command-reponse protocol.
Commands are NULL-terminated ASCII strings, one per UDP socket.
Each command has a corresponding response.
Every command is of the form:
CMD <cmdtype> [params]
The <cmdtype> is the actual command.
Parameters are optional depending on the commands type.
Every response is of the form:
RSP <cmdtype> <status> [result]
The <status> is 0 for success and a non-zero error code for failure.
Successful responses may include results, depending on the command type.
Power Control
POWEROFF shuts off transmitter power and stops the demodulator.
CMD POWEROFF
RSP POWEROFF <status>
POWERON starts the transmitter and starts the demodulator. Initial power level is very low.
This command fails if the transmitter and receiver are not yet tuned.
This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
If the transceiver is already on, it response with success to this command.
CMD POWERON
RSP POWERON <status>
SETPOWER sets output power in dB wrt full scale.
This command fails if the transmitter and receiver are not running.
CMD SETPOWER <dB>
RSP SETPOWER <status> <dB>
ADJPOWER adjusts power by the given dB step. Response returns resulting power level wrt full scale.
This command fails if the transmitter and receiver are not running.
CMD ADJPOWER <dBStep>
RSP ADJPOWER <status> <dBLevel>
Tuning Control
RXTUNE tunes the receiver to a given frequency in kHz.
This command fails if the receiver is already running.
(To re-tune you stop the radio, re-tune, and restart.)
This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
CMD RXTUNE <kHz>
RSP RXTUNE <status> <kHz>
TXTUNE tunes the transmitter to a given frequency in kHz.
This command fails if the transmitter is already running.
(To re-tune you stop the radio, re-tune, and restart.)
This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
CMD TXTUNE <kHz>
RSP TXTUNE <status> <kHz>
Timeslot Control
SETSLOT sets the format of the uplink timeslots in the ARFCN.
The <timeslot> indicates the timeslot of interest.
The <chantype> indicates the type of channel that occupies the timeslot.
A chantype of zero indicates the timeslot is off.
CMD SETSLOT <timeslot> <chantype>
RSP SETSLOT <status> <timeslot> <chantype>
Messages on the per-ARFCN Data Interface
Messages on the data interface carry one radio burst per UDP message.
Received Data Burst
1 byte timeslot index
4 bytes GSM frame number, big endian
1 byte RSSI in -dBm
2 bytes correlator timing offset in 1/256 symbol steps, 2's-comp, big endian
148 bytes soft symbol estimates, 0 -> definite "0", 255 -> definite "1"
Transmit Data Burst
1 byte timeslot index
4 bytes GSM frame number, big endian
1 byte transmit level wrt ARFCN max, -dB (attenuation)
148 bytes output symbol values, 0 & 1
Release history:
Release Name SVN Reposiory SVN Rev Comments
1.0 (none) SF.net ?? completed L1, L2
1.1 Arnaudville GNU Radio r10019 (trunk)
1.2 Breaux Bridge GNU Radio r10088 (trunk) GNU Build, very early assignment
1.3 Carencro KSP r1 (trunk) first post-injunction release
1.4 Donaldsonville KSP r23 (trunk) fixed Ubuntu build error
1.5 Eunice KSP r39 (trunk) fixed L2 bugs related to segmentation
removed incomplete SMS directory
moved "abort" calls into L3 subclasses
1.6 New Iberia KSP r130 (trunk) import of all 2.2 improvements to non-SMS release
2.0 St. Francisville KSP r54 (smswork) SMS support
file-based configuration
2.1 Grand Coteau KSP r70 (smswork) DTMF support
fixed more Linux-related build errors
-lpthread
TLMessage constructor
expanded stack to prevent overflows in Linux
moved gSIPInterface to main app
fixed iterator bug in Pager
2.2 Houma KSP r122 (smswork) added LEGAL notice
removed Assert classes
stop paging on page response
fixed Pager-spin bug
fixed Transceiver spin bugs
fixed 2^32 microsecond rollover bug
reduced stack footprints in Transceiver
fixed SMS timestamps
check LAI before using TMSI in LUR
reduced memory requirement by 75%
removed PagerTest
fixed stale-transaction bug in paging handler
fixed USRP clock rollover bug
faster call connection
new USRPDevice design
2.3 Jean Lafitte KSP r190? (trunk) check for out-of-date RACH bursts
better TRX-GSM clock sync
formal logging system
command line interface
emergency call setup
2.4 Kinder KSP r208? (trunk) fixed BCCH neighbor list bug
support for neighbor lists
fixed support for non-local Asterisk servers
cleaner configuration management
more realtime control of BCCH parameters
proper rejection of Hold messages
fixed L3 hanging bug in MTDCheckBYE
2.4.1 Kinder KSP r462 fixed lots of valgrind errors
2.4.2 Kinder KSP r482 zero-length calling party number bug
g++ 4.4 #includes
2.5 Lacassine KSP r551 imported Joshua Lackey patches
SIP fixes from Anne Kwong
SIP fixes from testing with SMS server
L3 TI handling fixes
SMS server support
GNU Radio 3.2 compatibility
configurable max range and LU-reject cause
"page" & "testcall" CLI features
2.5.1 Lacassine KSP r595 fixed some build bugs for some Linux distros
2.5.2 Lacassine KSP r630 fixed channel assignment bug for Nokia DCT4+ handsets
2.5.3 Lacassine KSP r756 merged fix for transceiver startup crash
due to use of uninitialized variables (r646)
merged fix for fusb bug from trunk (r582)
2.5.4 Lacassine KSP r812 merged fixes to build under latest Fedora and
to build with git GnuRadio (r814)
2.6 Mamou KSP r886 fixed infamous fusb bug (r582)
fixed idle-filling table size bug
smoother uplink power control
load-limiting downlink power control
new "config" features (optional, static)
IMEI interrogation
fixed MOD "missing FIFO" bug
configurable short code features
fixed transceiver startup crash (r646)
readline support is back
fixed timing advance bug (r844)
added CLI "chans" command
track time-of-use in TMSI table (r844)
added CLI "noise" command (r844)
added CLI "rxpower" command (r844)
added CLI "unconfig" command
2.7 Natchitoches Range rxxx (never released publicly)
converted TMSITable to sqlite3 (r902)
sqlite3-based configuration (r???)
converted Logger to syslogd (r903)
added support for rest octets (r1022)
external database for transaction reporting (r1184)
external database for channel status reporting (r1203)
in-call delivery and submission of text messages (r1231)
RFC-2833 DMTF (r1249)
2.8 Opelousas Range rxxx move databases to /etc and /var
RRLP aiding support

View File

@@ -22,6 +22,8 @@
*/
#include <stdio.h>
#include <iomanip> // std::setprecision
#include <fstream>
#include "Transceiver.h"
#include <Logger.h>
@@ -140,18 +142,25 @@ bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc)
}
Transceiver::Transceiver(int wBasePort,
const char *wTRXAddress,
size_t wSPS, size_t wChans,
GSM::Time wTransmitLatency,
RadioInterface *wRadioInterface)
const char *wTRXAddress,
size_t wSPS, size_t wChans,
GSM::Time wTransmitLatency,
RadioInterface *wRadioInterface,
double wRssiOffset)
: mBasePort(wBasePort), mAddr(wTRXAddress),
mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
rssiOffset(wRssiOffset),
mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0)
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0), mWriteBurstToDiskMask(0)
{
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()
@@ -459,9 +468,15 @@ void Transceiver::setModulus(size_t timeslot, size_t chan)
Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
size_t 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 };
TransceiverState *state = &mStates[chan];
unsigned burstTN = currTime.TN();
unsigned burstFN = currTime.FN();
int subch;
switch (state->chanType[burstTN]) {
case NONE:
@@ -471,16 +486,25 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
return IDLE;
break;
case I:
// TODO: Are we expecting RACH on an IDLE frame?
/* if (burstFN % 26 == 25)
return IDLE;*/
if (mHandover[burstTN][0])
return RACH;
return TSC;
/*if (burstFN % 26 == 25)
return IDLE;
else
return TSC;*/
break;
case II:
subch = tchh_subslot[burstFN % 26];
if (subch == 1)
return IDLE;
if (mHandover[burstTN][0])
return RACH;
return TSC;
break;
case III:
subch = tchh_subslot[burstFN % 26];
if (mHandover[burstTN][subch])
return RACH;
return TSC;
break;
case IV:
@@ -495,6 +519,8 @@ 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;
@@ -502,6 +528,8 @@ 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;
@@ -531,13 +559,13 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
* Detect RACH synchronization sequence within a burst. No equalization
* is used or available on the RACH channel.
*/
bool Transceiver::detectRACH(TransceiverState *state,
signalVector &burst,
complex &amp, float &toa)
int Transceiver::detectRACH(TransceiverState *state,
signalVector &burst,
complex &amp, float &toa)
{
float threshold = 6.0;
return detectRACHBurst(burst, threshold, mSPSRx, &amp, &toa);
return detectRACHBurst(burst, threshold, mSPSRx, amp, toa);
}
/*
@@ -545,12 +573,13 @@ bool Transceiver::detectRACH(TransceiverState *state,
* state information and channel estimate if necessary. Equalization
* is currently disabled.
*/
bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
complex &amp, float &toa, GSM::Time &time)
int Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
complex &amp, float &toa, GSM::Time &time)
{
int success;
int tn = time.TN();
float chanOffset, threshold = 5.0;
bool noise, needDFE = false, estimateChan = false;
bool needDFE = false, estimateChan = false;
double elapsed = time - state->chanEstimateTime[tn];
signalVector *chanResp;
@@ -565,17 +594,18 @@ bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
}
/* Detect normal burst midambles */
if (!analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, &amp,
&toa, mMaxExpectedDelay, estimateChan,
&chanResp, &chanOffset)) {
return false;
success = analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp,
toa, mMaxExpectedDelay, estimateChan,
&chanResp, &chanOffset);
if (success <= 0) {
return success;
}
noise = state->mNoiseLev;
state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
/* Set equalizer if unabled */
if (needDFE && estimateChan) {
float noise = state->mNoiseLev;
state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
state->chanResponse[tn] = chanResp;
state->chanRespOffset[tn] = chanOffset;
state->chanRespAmplitude[tn] = amp;
@@ -588,7 +618,7 @@ bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
state->chanEstimateTime[tn] = time;
}
return true;;
return 1;
}
/*
@@ -611,20 +641,33 @@ SoftVector *Transceiver::demodulate(TransceiverState *state,
return demodulateBurst(burst, mSPSRx, amp, toa);
}
void writeToFile(radioVector *radio_burst, size_t chan)
{
GSM::Time time = radio_burst->getTime();
std::ostringstream fname;
fname << chan << "_" << time.FN() << "_" << time.TN() << ".fc";
std::ofstream outfile (fname.str().c_str(), std::ofstream::binary);
outfile.write((char*)radio_burst->getVector()->begin(), radio_burst->getVector()->size() * 2 * sizeof(float));
outfile.close();
}
/*
* Pull bursts from the FIFO and handle according to the slot
* and burst correlation type. Equalzation is currently disabled.
*/
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
int &timingOffset, size_t chan)
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
double &timingOffset, double &noise,
size_t chan)
{
bool success, equalize = false;
int success;
bool equalize = false;
complex amp;
float toa, pow, max = -1.0, avg = 0.0;
int max_i = -1;
signalVector *burst;
SoftVector *bits = NULL;
TransceiverState *state = &mStates[chan];
isRssiValid = false;
/* Blocking FIFO read */
radioVector *radio_burst = mReceiveFIFO[chan]->read();
@@ -635,7 +678,15 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
GSM::Time time = radio_burst->getTime();
CorrType type = expectedCorrType(time, chan);
if ((type == OFF) || (type == IDLE)) {
/* Debug: dump bursts to disk */
/* bits 0-7 - chan 0 timeslots
* bits 8-15 - chan 1 timeslots */
if (mWriteBurstToDiskMask & ((1<<time.TN()) << (8*chan)))
writeToFile(radio_burst, chan);
/* No processing if the timeslot is off.
* Not even power level or noise calculation. */
if (type == OFF) {
delete radio_burst;
return NULL;
}
@@ -659,7 +710,25 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
/* Average noise on diversity paths and update global levels */
burst = radio_burst->getVector(max_i);
avg = sqrt(avg / radio_burst->chans());
state->mNoiseLev = state->mNoises.avg();
wTime = time;
RSSI = 20.0 * log10(rxFullScale / avg);
/* RSSI estimation are valid */
isRssiValid = true;
if (type == IDLE) {
/* Update noise levels */
state->mNoises.insert(avg);
state->mNoiseLev = state->mNoises.avg();
noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
delete radio_burst;
return NULL;
} else {
/* Do not update noise levels */
noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
}
/* Detect normal or RACH bursts */
if (type == TSC)
@@ -667,33 +736,27 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
else
success = detectRACH(state, *burst, amp, toa);
/* Update noise average if no bust detected or alert on error */
/* Alert an error and exit */
if (success <= 0) {
if (!success) {
state->mNoises.insert(avg);
} else if (success == -SIGERR_CLIP) {
LOG(ALERT) << "Clipping detected on RACH input";
} else if (success < 0) {
LOG(ALERT) << "Unhandled RACH error";
if (success == -SIGERR_CLIP) {
LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
} else if (success != SIGERR_NONE) {
LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
}
delete radio_burst;
return NULL;
}
timingOffset = toa / mSPSRx;
/* Demodulate and set output info */
if (equalize && (type != TSC))
equalize = false;
if (avg - state->mNoiseLev > 0.0)
bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
wTime = time;
RSSI = (int) floor(20.0 * log10(rxFullScale / avg));
timingOffset = (int) round(toa * 256.0 / mSPSRx);
bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
delete radio_burst;
return bits;
}
@@ -743,6 +806,24 @@ 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;
}
}
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
@@ -836,6 +917,14 @@ void Transceiver::driveControl(size_t chan)
sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode);
}
else if (strcmp(command,"_SETBURSTTODISKMASK")==0) {
// debug command! may change or disapear without notice
// set a mask which bursts to dump to disk
int mask;
sscanf(buffer,"%3s %s %d",cmdcheck,command,&mask);
mWriteBurstToDiskMask = mask;
sprintf(response,"RSP _SETBURSTTODISKMASK 0 %d",mask);
}
else {
LOG(WARNING) << "bogus command " << command << " on control interface.";
sprintf(response,"RSP ERR 1");
@@ -892,27 +981,34 @@ void Transceiver::driveReceiveRadio()
void Transceiver::driveReceiveFIFO(size_t chan)
{
SoftVector *rxBurst = NULL;
int RSSI;
int TOA; // in 1/256 of a symbol
double RSSI; // in dBFS
double dBm; // in dBm
double TOA; // in symbols
int TOAint; // in 1/256 symbols
double noise; // noise level in dBFS
GSM::Time burstTime;
bool isRssiValid; // are RSSI, noise and burstTime valid
rxBurst = pullRadioVector(burstTime, RSSI, TOA, chan);
rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan);
if (rxBurst) {
dBm = RSSI+rssiOffset;
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
LOG(DEBUG) << std::fixed << std::right
<< " time: " << burstTime
<< " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -dBm << "dBm"
<< " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -(noise+rssiOffset) << "dBm"
<< " TOA: " << std::setw(5) << std::setprecision(2) << TOA
<< " bits: " << *rxBurst;
LOG(DEBUG) << "burst parameters: "
<< " time: " << burstTime
<< " RSSI: " << RSSI
<< " TOA: " << TOA
<< " bits: " << *rxBurst;
char burstString[gSlotLen+10];
burstString[0] = burstTime.TN();
for (int i = 0; i < 4; i++)
burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
burstString[5] = RSSI;
burstString[6] = (TOA >> 8) & 0x0ff;
burstString[7] = TOA & 0x0ff;
burstString[5] = (int)dBm;
burstString[6] = (TOAint >> 8) & 0x0ff;
burstString[7] = TOAint & 0x0ff;
SoftVector::iterator burstItr = rxBurst->begin();
for (unsigned int i = 0; i < gSlotLen; i++) {

View File

@@ -97,10 +97,11 @@ public:
@param radioInterface associated radioInterface object
*/
Transceiver(int wBasePort,
const char *TRXAddress,
size_t wSPS, size_t chans,
GSM::Time wTransmitLatency,
RadioInterface *wRadioInterface);
const char *TRXAddress,
size_t wSPS, size_t chans,
GSM::Time wTransmitLatency,
RadioInterface *wRadioInterface,
double wRssiOffset);
/** Destructor */
~Transceiver();
@@ -181,6 +182,8 @@ private:
double txFullScale; ///< full scale input to radio
double rxFullScale; ///< full scale output to radio
double rssiOffset; ///< RSSI to dBm conversion offset
/** modulate and add a burst to the transmit queue */
void addRadioVector(size_t chan, BitVector &bits,
int RSSI, GSM::Time &wTime);
@@ -192,8 +195,9 @@ private:
void pushRadioVector(GSM::Time &nowTime);
/** Pull and demodulate a burst from the receive FIFO */
SoftVector *pullRadioVector(GSM::Time &wTime, int &RSSI,
int &timingOffset, size_t chan = 0);
SoftVector *pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
double &timingOffset, double &noise,
size_t chan = 0);
/** Set modulus for specific timeslot */
void setModulus(size_t timeslot, size_t chan);
@@ -205,14 +209,14 @@ private:
void writeClockInterface(void);
/** Detect RACH bursts */
bool detectRACH(TransceiverState *state,
signalVector &burst,
complex &amp, float &toa);
int detectRACH(TransceiverState *state,
signalVector &burst,
complex &amp, float &toa);
/** Detect normal bursts */
bool detectTSC(TransceiverState *state,
signalVector &burst,
complex &amp, float &toa, GSM::Time &time);
int detectTSC(TransceiverState *state,
signalVector &burst,
complex &amp, float &toa, GSM::Time &time);
/** Demodulat burst and output soft bits */
SoftVector *demodulate(TransceiverState *state,
@@ -223,11 +227,13 @@ private:
int mSPSRx; ///< number of samples per Rx symbol
size_t mChans;
bool mOn; ///< flag to indicate that transceiver is powered on
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
unsigned mTSC; ///< the midamble sequence code
unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
unsigned mWriteBurstToDiskMask; ///< debug: bitmask to indicate which timeslots to dump to disk
std::vector<TransceiverState> mStates;

View File

@@ -210,8 +210,7 @@ uhd::time_spec_t convert_time(TIMESTAMP ticks, double rate)
TIMESTAMP convert_time(uhd::time_spec_t ts, double rate)
{
TIMESTAMP ticks = ts.get_full_secs() * rate;
return ts.get_tick_count(rate) + ticks;
return (TIMESTAMP)(ts.get_real_secs() * rate + 0.5);
}
/*
@@ -290,7 +289,7 @@ public:
uhd_device(size_t sps, size_t chans, bool diversity, double offset);
~uhd_device();
int open(const std::string &args, bool extref);
int open(const std::string &args, bool extref, bool swap_channels);
bool start();
bool stop();
bool restart();
@@ -473,18 +472,24 @@ void uhd_device::init_gains()
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++) {
usrp_dev->set_tx_gain((tx_gain_min + tx_gain_max) / 2, 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);
tx_gains[i] = usrp_dev->get_tx_gain(i);
}
for (size_t i = 0; i < rx_gains.size(); i++) {
usrp_dev->set_rx_gain((rx_gain_min + rx_gain_max) / 2, 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);
rx_gains[i] = usrp_dev->get_rx_gain(i);
}
@@ -582,7 +587,7 @@ double uhd_device::setTxGain(double db, size_t chan)
tx_gains[chan] = usrp_dev->get_tx_gain(chan);
LOG(INFO) << "Set TX gain to " << tx_gains[chan] << "dB";
LOG(INFO) << "Set TX gain to " << tx_gains[chan] << "dB (asked for " << db << "dB)";
return tx_gains[chan];
}
@@ -597,7 +602,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";
LOG(INFO) << "Set RX gain to " << rx_gains[chan] << "dB (asked for " << db << "dB)";
return rx_gains[chan];
}
@@ -694,7 +699,7 @@ bool uhd_device::parse_dev_type()
return true;
}
int uhd_device::open(const std::string &args, bool extref)
int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
{
// Find UHD devices
uhd::device_addr_t addr(args);
@@ -720,7 +725,7 @@ int uhd_device::open(const std::string &args, bool extref)
// Verify and set channels
if ((dev_type == B210) && (chans == 2)) {
} else if ((dev_type == UMTRX) && (chans == 2)) {
uhd::usrp::subdev_spec_t subdev_spec("A:0 B:0");
uhd::usrp::subdev_spec_t subdev_spec(swap_channels?"B:0 A:0":"A:0 B:0");
usrp_dev->set_tx_subdev_spec(subdev_spec);
usrp_dev->set_rx_subdev_spec(subdev_spec);
} else if (chans != 1) {
@@ -1115,7 +1120,7 @@ uhd::tune_request_t uhd_device::select_freq(double freq, size_t chan, bool tx)
uhd::tune_request_t treq(freq);
if (dev_type == UMTRX) {
if (offset > 0.0)
if (offset != 0.0)
return uhd::tune_request_t(freq, offset);
// Don't use DSP tuning, because LMS6002D PLL steps are small enough.
@@ -1126,6 +1131,7 @@ uhd::tune_request_t uhd_device::select_freq(double freq, size_t chan, bool tx)
treq.rf_freq = freq;
treq.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
treq.dsp_freq = 0.0;
return treq;
} else if (chans == 1) {
if (offset == 0.0)
return treq;
@@ -1430,6 +1436,19 @@ ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp)
if ((timestamp + len) <= time_end)
return ERROR_TIMESTAMP;
if (timestamp < time_end) {
LOG(ERR) << "Overwriting old buffer data: timestamp="<<timestamp<<" time_end="<<time_end;
uhd::time_spec_t ts = convert_time(timestamp, clk_rt);
LOG(DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << convert_time(ts, clk_rt) << ") rate=" << clk_rt;
// Do not return error here, because it's a rounding error and is not fatal
}
if (timestamp > time_end && time_end != 0) {
LOG(ERR) << "Skipping buffer data: timestamp="<<timestamp<<" time_end="<<time_end;
uhd::time_spec_t ts = convert_time(timestamp, clk_rt);
LOG(DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << convert_time(ts, clk_rt) << ") rate=" << clk_rt;
// Do not return error here, because it's a rounding error and is not fatal
}
// Starting index
size_t write_start = (data_start + (timestamp - time_start)) % buf_len;

View File

@@ -89,7 +89,7 @@ USRPDevice::USRPDevice(size_t sps, size_t, bool)
#endif
}
int USRPDevice::open(const std::string &, bool)
int USRPDevice::open(const std::string &, bool, bool)
{
writeLock.unlock();

View File

@@ -99,7 +99,7 @@ private:
USRPDevice(size_t sps, size_t chans = 1, bool diversity = false);
/** Instantiate the USRP */
int open(const std::string &, bool);
int open(const std::string &, bool, bool);
/** Start the USRP */
bool start();

View File

@@ -70,6 +70,8 @@ struct trx_config {
Transceiver::FillerType filler;
bool diversity;
double offset;
double rssi_offset;
bool swap_channels;
};
ConfigurationTable gConfig;
@@ -185,6 +187,8 @@ bool trx_setup_config(struct trx_config *config)
ost << " C0 Filler Table......... " << fillstr << std::endl;
ost << " Diversity............... " << divstr << std::endl;
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;
return true;
@@ -240,7 +244,7 @@ Transceiver *makeTransceiver(struct trx_config *config, RadioInterface *radio)
VectorFIFO *fifo;
trx = new Transceiver(config->port, config->addr.c_str(), config->sps,
config->chans, GSM::Time(3,0), radio);
config->chans, GSM::Time(3,0), radio, config->rssi_offset);
if (!trx->init(config->filler, config->rtsc)) {
LOG(ALERT) << "Failed to initialize transceiver";
delete trx;
@@ -292,7 +296,9 @@ static void print_help()
" -c Number of ARFCN channels (default=1)\n"
" -f Enable C0 filler table\n"
" -o Set baseband frequency offset (default=auto)\n"
" -r Random burst test mode with TSC\n",
" -r Random burst test mode with TSC\n"
" -R RSSI to dBm offset in dB (default=0)\n"
" -S Swap channels (UmTRX only)\n",
"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
}
@@ -308,8 +314,10 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
config->filler = Transceiver::FILLER_ZERO;
config->diversity = false;
config->offset = 0.0;
config->rssi_offset = 0.0;
config->swap_channels = false;
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:")) != -1) {
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:S")) != -1) {
switch (option) {
case 'h':
print_help();
@@ -349,6 +357,12 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
config->rtsc = atoi(optarg);
config->filler = Transceiver::FILLER_RAND;
break;
case 'R':
config->rssi_offset = atof(optarg);
break;
case 'S':
config->swap_channels = true;
break;
default:
print_help();
exit(0);
@@ -393,7 +407,7 @@ int main(int argc, char *argv[])
/* Create the low level device object */
usrp = RadioDevice::make(config.sps, config.chans,
config.diversity, config.offset);
type = usrp->open(config.dev_args, config.extref);
type = usrp->open(config.dev_args, config.extref, config.swap_channels);
if (type < 0) {
LOG(ALERT) << "Failed to create radio device" << std::endl;
goto shutdown;

View File

@@ -41,7 +41,7 @@ class RadioDevice {
bool diversity = false, double offset = 0.0);
/** Initialize the USRP */
virtual int open(const std::string &args = "", bool extref = false)=0;
virtual int open(const std::string &args = "", bool extref = false, bool swap_channels = false)=0;
virtual ~RadioDevice() { }

View File

@@ -28,6 +28,7 @@
#include "sigProcLib.h"
#include "GSMCommon.h"
#include "Logger.h"
extern "C" {
#include "convolve.h"
@@ -1284,12 +1285,12 @@ static float computePeakRatio(signalVector *corr,
complex *peak;
float rms, avg = 0.0;
peak = corr->begin() + (int) rint(toa);
/* Check for bogus results */
if ((toa < 0.0) || (toa > corr->size()))
return 0.0;
peak = corr->begin() + (int) rint(toa);
for (int i = 2 * sps; i <= 5 * sps; i++) {
if (peak - i >= corr->begin()) {
avg += (peak - i)->norm2();
@@ -1372,18 +1373,74 @@ static int detectBurst(signalVector &burst,
return 1;
}
static int detectClipping(signalVector &burst, float thresh)
static float maxAmplitude(signalVector &burst)
{
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;
}
float max = 0.0;
for (size_t i = 0; i < burst.size(); i++) {
if (fabs(burst[i].real()) > max)
max = fabs(burst[i].real());
if (fabs(burst[i].imag()) > max)
max = fabs(burst[i].imag());
}
return 0;
return max;
}
/*
* RACH/Normal burst detection with clipping detection
*
* Correlation window parameters:
* target: Tail bits + burst length
* head: Search symbols before target
* tail: Search symbols after target
*/
int detectGeneralBurst(signalVector &rxBurst,
float thresh,
int sps,
complex &amp,
float &toa,
int target, int head, int tail,
CorrelationSequence *sync)
{
int rc, start, len;
bool clipping = false;
signalVector *corr;
if ((sps != 1) && (sps != 4))
return -SIGERR_UNSUPPORTED;
// Detect potential clipping
// We still may be able to demod the burst, so we'll give it a try
// and only report clipping if we can't demod.
float maxAmpl = maxAmplitude(rxBurst);
if (maxAmpl > CLIP_THRESH) {
LOG(DEBUG) << "max burst amplitude: " << maxAmpl << " is above the clipping threshold: " << CLIP_THRESH << std::endl;
clipping = true;
}
start = (target - head) * sps - 1;
len = (head + tail) * sps;
corr = new signalVector(len);
rc = detectBurst(rxBurst, *corr, sync,
thresh, sps, &amp, &toa, start, len);
delete corr;
if (rc < 0) {
return -SIGERR_INTERNAL;
} else if (!rc) {
amp = 0.0f;
toa = 0.0f;
return clipping?-SIGERR_CLIP:SIGERR_NONE;
}
/* Subtract forward search bits from delay */
toa -= head * sps;
return 1;
}
/*
* RACH burst detection
*
@@ -1393,53 +1450,23 @@ static int detectClipping(signalVector &burst, float thresh)
* tail: Search 10 symbols after target
*/
int detectRACHBurst(signalVector &rxBurst,
float thresh,
int sps,
complex *amp,
float *toa)
float thresh,
int sps,
complex &amp,
float &toa)
{
int rc, start, target, head, tail, len;
float _toa;
complex _amp;
signalVector *corr;
int rc, target, head, tail;
CorrelationSequence *sync;
if ((sps != 1) && (sps != 4))
return -SIGERR_UNSUPPORTED;
if (detectClipping(rxBurst, CLIP_THRESH))
return -SIGERR_CLIP;
target = 8 + 40;
head = 4;
tail = 10;
start = (target - head) * sps - 1;
len = (head + tail) * sps;
sync = gRACHSequence;
corr = new signalVector(len);
rc = detectBurst(rxBurst, *corr, sync,
thresh, sps, &_amp, &_toa, start, len);
delete corr;
rc = detectGeneralBurst(rxBurst, thresh, sps, amp, toa,
target, head, tail, sync);
if (rc < 0) {
return -SIGERR_INTERNAL;
} else if (!rc) {
if (amp)
*amp = 0.0f;
if (toa)
*toa = 0.0f;
return 0;
}
/* Subtract forward search bits from delay */
if (toa)
*toa = _toa - head * sps;
if (amp)
*amp = _amp;
return 1;
return rc;
}
/*
@@ -1451,60 +1478,32 @@ int detectRACHBurst(signalVector &rxBurst,
* tail: Search 4 symbols + maximum expected delay
*/
int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
int sps, complex *amp, float *toa, unsigned max_toa,
int sps, complex &amp, float &toa, unsigned max_toa,
bool chan_req, signalVector **chan, float *chan_offset)
{
int rc, start, target, head, tail, len;
complex _amp;
float _toa;
signalVector *corr;
int rc, target, head, tail;
CorrelationSequence *sync;
if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
if ((tsc < 0) || (tsc > 7))
return -SIGERR_UNSUPPORTED;
if (detectClipping(rxBurst, CLIP_THRESH))
return -SIGERR_CLIP;
target = 3 + 58 + 16 + 5;
head = 4;
tail = 4 + max_toa;
start = (target - head) * sps - 1;
len = (head + tail) * sps;
sync = gMidambles[tsc];
corr = new signalVector(len);
rc = detectBurst(rxBurst, *corr, sync,
thresh, sps, &_amp, &_toa, start, len);
delete corr;
if (rc < 0) {
return -SIGERR_INTERNAL;
} else if (!rc) {
if (amp)
*amp = 0.0f;
if (toa)
*toa = 0.0f;
return 0;
}
/* Subtract forward search bits from delay */
_toa -= head * sps;
if (toa)
*toa = _toa;
if (amp)
*amp = _amp;
rc = detectGeneralBurst(rxBurst, thresh, sps, amp, toa,
target, head, tail, sync);
/* Equalization not currently supported */
if (chan_req) {
if (rc > 0 && chan_req) {
*chan = new signalVector(6 * sps);
if (chan_offset)
*chan_offset = 0.0;
}
return 1;
return rc;
}
signalVector *decimateVector(signalVector &wVector, size_t factor)

View File

@@ -192,8 +192,8 @@ bool energyDetect(signalVector &rxBurst,
int detectRACHBurst(signalVector &rxBurst,
float detectThreshold,
int sps,
complex *amplitude,
float* TOA);
complex &amplitude,
float &TOA);
/**
Normal burst correlator, detector, channel estimator.
@@ -210,15 +210,15 @@ int detectRACHBurst(signalVector &rxBurst,
@return positive if threshold value is reached, negative on error, zero otherwise
*/
int analyzeTrafficBurst(signalVector &rxBurst,
unsigned TSC,
float detectThreshold,
int sps,
complex *amplitude,
float *TOA,
unsigned TSC,
float detectThreshold,
int sps,
complex &amplitude,
float &TOA,
unsigned maxTOA,
bool requestChannel = false,
signalVector** channelResponse = NULL,
float *channelResponseOffset = NULL);
signalVector** channelResponse = NULL,
float *channelResponseOffset = NULL);
/**
Decimate a vector.

View File

@@ -1,5 +1,5 @@
if !ARCH_ARM
AM_CFLAGS = -Wall -std=gnu99 -march=native -I../common
AM_CFLAGS = -Wall -std=gnu99 -I../common
noinst_LTLIBRARIES = libarch.la

19
debian/changelog vendored Normal file
View File

@@ -0,0 +1,19 @@
osmo-trx (0.1.9~1) trusty; urgency=medium
* minor debian changes
* correct atom cross-compilation
* corrected build-time and run-time dependencies
-- Kirill Zakharenko <earwin@gmail.com> Thu, 23 Jul 2015 00:01:07 +0000
osmo-trx (0.1.9) trusty; urgency=medium
* Ask Ivan, really
-- Kirill Zakharenko <earwin@gmail.com> Thu, 16 Jul 2015 12:13:46 +0000
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 Normal file
View File

@@ -0,0 +1 @@
9

24
debian/control vendored Normal file
View File

@@ -0,0 +1,24 @@
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, libuhd-dev, libusb-1.0-0-dev, libboost-all-dev, hardening-wrapper
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 Normal file
View File

@@ -0,0 +1,25 @@
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

1
debian/osmo-trx.install vendored Normal file
View File

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

15
debian/rules vendored Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/make -f
DEB_BUILD_HARDENING=1
%:
dh $@ --with autoreconf
override_dh_auto_configure:
dh_auto_configure -- --without-sse CFLAGS="-DHAVE_SSE3 -march=atom -mtune=atom -O2" CXXFLAGS="-DHAVE_SSE3 -march=atom -mtune=atom -O2"
override_dh_shlibdeps:
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
override_dh_strip:
dh_strip --dbg-package=osmo-trx-dbg

1
debian/source/format vendored Normal file
View File

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

3
utils/clockdump.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
sudo tcpdump -i lo0 -A udp port 5700