Commit Graph

148 Commits

Author SHA1 Message Date
Alexander Chemeris 0b8aa00bc7 conditional load testing (selected at compile time), turned on by default. 2013-09-06 00:35:57 +04:00
Thomas Tsou 1ed2e27d19 Transceiver52M: Remove unused test code from main
The commented out test code is not maintained and behaviour is
unknown. Remove for clarity.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:51 -04:00
Thomas Tsou 91ac934749 Transceiver52M: Verify global config sanity at start
The configuration table is instantiated as a global variable with
no means to check constructor status. This means various types
of database failure conditions (e.g. file existence, permissions,
etc.) are not reported. This patch performs a small number of
checks to make sure that the configuration is sane.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou 7398a756ea Transceiver52M: Disable equalization for SPS greater than 1
Not supported by equalizer.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou 44389b80d5 Transceiver52M: Add command line device args passing
Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou 3e24f791dd Transceiver52M: Setup dual Laurent pulse filter
Provides improved transmit phase error performance below
1 degree RMS on certain devices. Requires use of 4
samples-per-symbol.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou ef7c258cbf Transceiver52M: Refactor RACH and TSC detection
Both RACH and normal bursts are detected with the same approach of
midamble correlation combined with peak-to-average ratio. The
difference is the midamble placements and lengths. Thus, there is
no reason to have independent implementations.

This patch creates a common call burstDetect(), while leaving the
correlation window indexing in the original calls.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou fb6e75789b Transceiver52M: Disable energy detector
The adaptive energy threshold gating suffers a near-far problem
at certain gain levels. This is due to exponential threshold
raising, but linear decreases. A large signal level followed by
a period low signal level causes comparatively weak signals to
go undetected. Additionally, the algorithm performs differently
at multiple RF gain and/or input scaling levels.

This patch switches solely to correlation based gating for burst
detection. The main computational load with this approach is
sub-sample peak interpolation, which we disable during intial
detection.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou 23ee9002b4 Transceiver52M: Add SSE floating point / integer conversion
Convertions are performed in multiples of 4 or 8. All loads are
considered unaligned.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou 98e58b9111 Transceiver52M: Add 4 samples-per-symbol Laurent pulse shape
When 4 samples-per-symbol operation is selected, replace the
existing pulse approximation, which becomes inaccurate with
non-unit oversampling, with the primary pulse, C0, from the
Laurent linear pulse approximation.

Pierre Laurent, "Exact and Approximate Construction of Digital Phase
  Modulations by Superposition of Amplitude Modulated Pulses", IEEE
  Transactions of Communications, Vol. 34, No. 2, Feb 1986.

Octave pulse generation code for the first three pulses of the
linear approximation are included.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou 0c260aecaf Transceiver52M: Reverse storage of convolution vectors
With convolution changes, we now assume that tap values for
filterting are stored in reverse. Along the same lines,
the tap values used during correlation are no longer stored
in reverse, however, they are still assumed to be conjugated.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:50 -04:00
Thomas Tsou acc9ee9fc0 Transceiver52M: Replace convolve and related calls with SSE implementation
This large patch replaced the convolve() call with an SSE vector
enabled version. The lower C and SSE intrinsic based code operates
on fixed and aligned vectors for the filter taps. The storage format
of interleaved I/Q for both complex and real vectors is maintained.

SSE filter tap values must:

  1. Start 16-byte aligned
  2. Number with a multiple of 4 between 4 and 20 for real taps
  3. Number with a multiple of 4 for complex taps

Non-compliant values will fall back to non-SSE usage. Fixed length
iterators mean that head and tail cases may require reallocation of
the input vector, which is automatically handled by the upper C++
interface.

Other calls are affected by these changes and adjusted or rewritten
accordingly. The underlying algorithms, however, are unchanged.

  generateGSMPulse()
  analyzeTrafficBurst()
  detectRACHBurst()

Intel SSE configuration is automatically detected and configured at
build time with Autoconf macros.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 06:07:33 -04:00
Thomas Tsou 9520ecd0c5 Transceiver52M: Generate RACH correlation sequence at initialization
There is no temporal dependency on when the RACH sequence is generated,
so there is no need for transceiver to create it in response to a
command from GSM core. If we power on the transceiver, we will need
the RACH sequence, so just allocate it during initialization.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 04:55:51 -04:00
Thomas Tsou ab599f8b6d Transceiver52M: Remove logging from signal processing core
The only logging outputs in the the signal processing library
are debug lines that generate copious amounts of output while
providing little useful information to the user. The relevant
information (time-of-arrival, channel gains, etc.) can and
should be logged from transceiver instance itself.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 04:55:51 -04:00
Thomas Tsou d6ed8c0b0e Transceiver52M: Add destructors to correlation seqeunce objects
Add destructor calls so we can avoid the nested vector deallocations.
Also remove the unnecessary pointer NULL checks prior to destruction.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 04:55:51 -04:00
Thomas Tsou c8ce878daf Transceiver52M: Make GSM pulse filter internal to implementation
There is no reason expose the pulse shaping filter outside of the
signal processing calls. The main transceiver object makes no use
of the filter and there's no reason to pass it around.

Initialize the pulse shape with the signal processing library, and
maintain an internal static member like many of the other library
variables. Similarly destroy the object when the library is closed.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-05 04:55:30 -04:00
Thomas Tsou e01e1b3fa8 Transceiver52M: Rename samples-per-symbol variable names
Because repeatedly typing mSamplesPerSymbol is giving me
carpal tunnel syndrome. Replace with the much shorter,
easier to type, and just as clear name of 'sps'.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-09-02 13:27:11 +08:00
Alexander Chemeris c5da6607b4 Transceiver52M: Fix crash in uhd_device destructor due to deleting statically allocated memory. 2013-07-14 14:59:00 +04:00
Thomas Tsou 42ade041d7 Transceiver52M: Setup independent gain and tune elements for dual channel 2013-07-14 13:37:03 +04:00
Thomas Tsou 5e18001bb0 Transceiver52M: Disable TSC check on slot setting 2013-07-14 13:36:55 +04:00
Thomas Tsou 621e52ab4a Transceiver52M: Disable dynamic filler table setting and fix deallocation 2013-07-14 13:36:42 +04:00
Alexander Chemeris f86aa2c923 Transceiver52M: Fix build in the new repository. 2013-06-24 01:57:31 +04:00
Thomas Tsou 48f8fb34aa Transceiver52M: Setup UmTRX dual carrier support 2013-06-24 01:51:03 +04:00
Thomas Tsou 40c3d0a6d9 transceiver: mcbts: remove unused call in drive loop
Inside the drive loop addRadioVector() is duplicate call that was
not removed from the previous separation of the main loop and
transceiver instances.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:03 +04:00
Thomas Tsou 41c6657938 multi-arfcn: refactor to match upstream GSM core
This patch aligns the multicarrier (MC) USRP code with
released GSM core changes that accommodate the MC RAD1.
Primary changes are:

     1. Runtime setting of number of channelizer paths
     2. Matching channelizer path to ARFCN mapping of GSM core
     3. Use a single clock update socket on the drive loop
     4. Match transceiver data and control socket ports

Setting of channelizer paths (or width) was previously fixed
at compile time. In either case, channelizer width is limited
by the sample rate of the device and channel spacing of the
maximally decimated filterbank. Available settings are 1, 5,
and 10 channels, which accommodate any number of ARFCN's in
between. Also add the frequency offsets to handle the effective
shift in setting RF frequency.

Previous assumption was to place C0 at the center frequency,
but RAD1 assumes C0 at the leftmost carrier, so adjust
accordingly.

The rest is general consolidation to mostly match the RAD1
interaction with GSM core. There is some loss of flexibility to
run, say, multiple independent instances of OpenBTS through a
single bank of channelized transceivers. But, the better
compatibility and reduction in code is the appropriate tradeoff.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou cd576c9636 uhd: fix local overflow handling of buffer reads
This patches fixes the hypothetical bug in the read out of the
intermediate sample buffer after a local overflow condition.

Local overflows - occurring in the intermediate storage buffer
and not the UHD transport - should never occur; the existence
of a local overflow indicates a significant error elsewhere in
the system. For example, if timestamps or timing offsets are
ridiculously off, such errors may occur.

Nonetheless, handle errors anyways by taking the modulo value
of the calculated read index to stay within the buffer and avoid
seg faulting.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 3eeda4841d multi-arfcn, trx: create transceivers based on command line arg
Move from the hard coded case of 3 transceiver instances to a
command line determined value. 'M' potential channels will be
compiled into the build depending on preprocessor selections
in radioParams.h. The command line argument must be less M.

Channels are selected starting from 0, which is centered on the
RF tuning frequency. Subsequent channels are selected by shifting
outward from 0 (center) in a left before right pattern. Default
channel spacing is 400 kHz. The ordering for supported cases of
1, 5, and 10 path channelizers is as follows.

CHAN_M = 1

    { 0 }

CHAN_M = 5

    { 0, 1, 4, 2, 3 }

CHAN_M = 10

    { 0, 1, 9, 2, 8, 3, 7, 4, 6, 5}

Note: Channel 5 for the 10 channel case sits on the Nyquist
frequency and is therefor unusable.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 5d64491f9b transceiver, uhd: dynamically allocate async event thread
Similar to the previous commit titled,

"multi-arfcn, trx: allocate threads on heap and fix thread release"

there is the potential for a segfault on exit if the event thread
is never started. As before, address the issue by initializing
the Thread pointer with NULL and later allocating the object
immediately prior to use.

On stop or exit, allow the thread to exit by checking a condition
variable. If device is stopped or never started, the same variable
can be checked for state, which avoids attempts to deallocate an
empty pointer.

If there is a better method to shutdown / deallocate using the
OpenBTS thread library, please let me know.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou b5c450dfdf multi-arfcn, trx: attach FIFO's internally in transceiver
The original split-transceiver abstraction did not maintain
internal instances of the radio interface or drive loop.
The FIFO's were attached through external calls. The control
loop, however, made such an approach overly difficult, so
the transceiver now maintains pointers to the aforementioned
objects. In doing so, we no longer need external attachment
calls to setup the FIFO's.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou afb04f8b63 multi-arfcn, trx: fix infinite energy threshold bug
This fixes a bug where the energy threshold may reach infinity.

The transceiver energy detection threshold increase is
dependent on elapsed frames and the previous false detection
time. If we assume a (0,0) start time with the actual start
time - randomly determined - it's possible to get very
large elapsed frame counts at start. Once the threshold hits
'inf' further calculations are impossible and transceiver
is locked out from use.

Use the actual start time for initializing variables so
we avoid this scenario.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 5f13377b83 multi-arfcn, trx: handle thread exiting on shutdown
Previous approach was to allow stack unwinding to take care
shutdown and thread ending, which was unpredictable and
occasionally segfault. Attempt to shutdown more gracefully.

There are thread cancellation points in the transceiver code
using pthread_testcancel(), but the thread abstraction library
does not allow direct access to the pthread variables. This
prevents thread shutdown through pthread_cancel(). To get
around this, use boolean status values in the receive socket
service loops and main drive loop.

The socket read calls will block indefinitly, so shutdown
may cause the socket implementation to throw a SocketError
exception. Use of timeout values with reads does not seem to
work correctly or reliably, so catch the exception and ignore
if it occurs on shutdown.

The following error may appear as the socket is shutdown while
the Transceiver is blocking on read().

  DatagramSocket::read() failed: Bad file descriptor

So be it; the API doesn't allow us to do any more.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou a6ca73ca67 multi-arfcn, trx: allocate threads on heap and fix thread release
The underlying pthread of the Thread object isn't created until
Thread::start(). If the Thread object is contructed, but not
started, then the destructor will fail with a variety of
unpredictable errors such as the following or double free() in
certain cases.

Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x3811abed3e946178) at malloc.c:2972
2972      if (chunk_is_mmapped(p))

If the Thread object is stack allocated, but start() isn't called,
destructor is guaranteed to run and will fail. The previous
approach was to dynamically allocate threads, but not free them,
thus avoiding memory errors, but creating memory leaks.

To get around this limitation, dynamically allocate Thread objects
and initialize with NULL. Then allocate immediately prior to start
such that pthread allocation is tied to the Thread object
constructor. Deallocation can check that the Thread pointer is
valid through NULL or other tracking methods.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 5a37840dfa multi-arfcn, trx: remove unused reset() call in drive loop
This call is a remnant of the Transceiver / DriveLoop split. The
empty call is never used.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou ca5d35cce8 multi-arfcn, trx: remove unused attach call()
At one point an attach() call was used to connect
multiple transceivers to the radio interface. The
current approach is to pass the radio interface to
the transceiver instances through the constructor.
Remove the unused and deprecated call.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 507e6d4e12 multi-arfcn, trx: only deallocate radio resouces if started
Certain notable variables - sample buffers - are not
allocated until start(), which causes a segfault if the
transceiver is shutdown without the radio starting. Check
that the radio is 'started' before releasing in the
destructor.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 1f330a9801 transceiver: define virtual destructor for base device
Lack of an explicitly defined virtual destructor was
causing the empty default interface destructor to be
called, which created a memory leak at shutdown.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 7c6f58af7a multi-arfcn, trx: add and modify transceiver main for new interfaces
Add a transceiver main() for multi-arfcn use and modify single
channel transceiver for use with updated interfaces.

Setup multiTRX with 3 channels for default case.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:51:02 +04:00
Thomas Tsou 996f426c16 multi-arfcn, trx: split transceiver to handle multiple channels
This patch separates the 'Transceiver' into a multi-channel
I/O component and single channel component. The latter may
may have multiple instances. The receive FIFO is converted to
a thread-safe queue.

The 'TransceiverIO' continuously drives the receive and transmit
loops. In this process, bursts are driven into thread-safe FIFO's
and read from the priority queues. Filler bursts are inserted if
no transmit data is available.

Each 'Transceiver' instance attaches to the I/O object and creates
its own threads and sockets, which include blocking on the receive
FIFO for the attached channel. Each instance also handles its own
control loop and clock indications.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:50:59 +04:00
Thomas Tsou 711e6afddf multi-arfcn, trx: modify radio interface for multi-channel use
The radio interface needs to feed the device I/O buffers
synchronously in order to drive the channelizer. Asynchronous
channel access occurs opposite the radio interface through
a bank of thread-safe FIFO's or priority queue's on receive
and transmit sides respectively.

Setup 'M' channels and allow only a subset to be active at a
given time. When a channel is unused, there is no need to
feed the particular receive FIFO or pull data from the
channel priority queue.

Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:46:34 +04:00
Thomas Tsou 222688d3dc multi-arfcn, trx: add header wrappers for radio interface
Signed-off-by: Thomas Tsou <ttsou@vt.edu>
2013-06-24 01:46:34 +04:00
Thomas Tsou 20bc24d367 Transceiver52M: Add UmTRX support 2013-06-24 01:46:34 +04:00
Thomas Tsou 59796e1e3e Transceiver52M: Explicitly check for USRP2 device type
Before, we assumed that non-B100 device was implicitly a USRP2
(inclusive of N200/N210). Make the check explicit so that any
unknown device will causes an error and exit.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou 19a506dffa Transceiver52M: Use exception blocks for rate changes
UHD will throw if something goes awry in these sensitive sections,
so we should catch and shutdown gracefully. There is no recovery
if we can't set rates.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou fbd6e1c985 Transceiver52M: Allow tolerance in UHD sample rate selection
We're performance floating point comparisons so allow a
10 Hz offset when UHD does not return an exact sample rate;

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou 03669856b7 Transceiver52M: Set resampling option automatically based on device
Remove the built time resampling selection and link both options.
Move the normal push/pullBuffer() calls back to the base class and
overload them in the inherited resampling class.

USRP2/N2xx devices are the only devices that require resampling so
return that resampling is necessary on the device open(), which is
the point at which the device type will be known.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou 5d0e392b21 Transceiver52M: Set sample rate from within the radio device
The GSM transceiver only operates at a whole number multiple of
the GSM rate and doesn't care about the actual device rate and
if resampling is used. Therefore GSM specific portion of the
transceiver should only need to submit the samples-per-symbol
value to the device interface.

Then, the device should be able to determine the appropriate
sample rate (400 ksps or 270.833 ksps) and if resampling is
appropriate.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou 801ce60d4a Transceiver52M: Remove and rename oversampling variables
The transceiver only uses a single integer oversampling value,
which is more simply referred to as samples-per-symbol.

mRadioOversampling --> mSPS
mTransceiverOversampling (removed)

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou ed64e799bc Transceiver52M: Remove periodic alignment update from UHD build
Periodic timing alignment should never be required for UHD devices,
though the mechanism was used as a fallback mechanism should UHD
not properly recover after an underrun - as may occur in old
003.003.000 based revisions. This issue is not a concern in more
recent UHD releases and deprecates this code for legacy USRP1
use only.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou d1bcab2731 Transceiver52M: Add device offset correction table
Previously, two timing correction values were used for UHD devices
depending on the sample rate of 270.833e3 or 400e3 for native GSM or
resampled device rate respectively. The correction values compensate
for residual timing effects due to analog component delays, filters
lag times, and general fudge factors. These values are device
specific and over-generalized by the two value configuration.

This patch adds the following struct to store these correction
values by device type and sample rate - through samples-per-symbol.

struct uhd_dev_offset {
        enum uhd_dev_type type;
        int sps;
        double offset;
};

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:34 +04:00
Thomas Tsou 00493f1a41 Transceiver52M: Add UHD device type checking
UHD device type was previously detected, but only categorized in
terms of bus type, USB or Ethernet, and sample rate capability.
With the number of supported device increasing, we can no longer
easily group devices since we need to handle more and more
device-specific peculiarities. Some of these factors are managed
internally by the UHD driver, but other factors (e.g. timing
offsets) are specific to a single device.

Start by maintaining an enumerated list of relevant device types
that we can use for applying device specific operations. Also
rename the USB/Ethernet grouping to transmit window type because
that's what it is.

enum uhd_dev_type {
        USRP1,
        USRP2,
        B100,
        NUM_USRP_TYPES,
};

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2013-06-24 01:46:33 +04:00