aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/Transceiver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Transceiver52M/Transceiver.cpp')
-rw-r--r--Transceiver52M/Transceiver.cpp104
1 files changed, 77 insertions, 27 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 881633e..f5ddd9b 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -29,6 +29,7 @@
#include <fstream>
#include "Transceiver.h"
#include <Logger.h>
+#include <grgsm_vitac/grgsm_vitac.h>
extern "C" {
#include "osmo_signal.h"
@@ -135,11 +136,13 @@ bool TransceiverState::init(FillerType filler, size_t sps, float scale, size_t r
Transceiver::Transceiver(const struct trx_cfg *cfg,
GSM::Time wTransmitLatency,
RadioInterface *wRadioInterface)
- : cfg(cfg), mClockSocket(-1),
- mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
- mChans(cfg->num_chans), mOn(false), mForceClockInterface(false),
- mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(0),
- mMaxExpectedDelayNB(0), mWriteBurstToDiskMask(0)
+ : mChans(cfg->num_chans), cfg(cfg),
+ mCtrlSockets(mChans), mClockSocket(-1),
+ mTxPriorityQueues(mChans), mReceiveFIFO(mChans),
+ mRxServiceLoopThreads(mChans), mRxLowerLoopThread(nullptr), mTxLowerLoopThread(nullptr),
+ mTxPriorityQueueServiceLoopThreads(mChans), mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
+ mOn(false),mForceClockInterface(false), mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(0),
+ mMaxExpectedDelayNB(0), mWriteBurstToDiskMask(0), mVersionTRXD(mChans), mStates(mChans)
{
txFullScale = mRadioInterface->fullScaleInputValue();
rxFullScale = mRadioInterface->fullScaleOutputValue();
@@ -206,15 +209,10 @@ bool Transceiver::init()
return false;
}
+ initvita();
+
mDataSockets.resize(mChans, -1);
- mCtrlSockets.resize(mChans);
- mTxPriorityQueueServiceLoopThreads.resize(mChans);
- mRxServiceLoopThreads.resize(mChans);
- mTxPriorityQueues.resize(mChans);
- mReceiveFIFO.resize(mChans);
- mStates.resize(mChans);
- mVersionTRXD.resize(mChans);
/* Filler table retransmissions - support only on channel 0 */
if (cfg->filler == FILLER_DUMMY)
@@ -395,7 +393,7 @@ void Transceiver::addRadioVector(size_t chan, BitVector &bits,
else
burst = modulateBurst(bits, 8 + (wTime.TN() % 4 == 0), cfg->tx_sps);
- scaleVector(*burst, txFullScale * pow(10, -RSSI / 10));
+ scaleVector(*burst, txFullScale * pow(10, (double) -RSSI / 20));
radio_burst = new radioVector(wTime, burst);
@@ -583,7 +581,7 @@ CorrType Transceiver::expectedCorrType(GSM::Time currTime,
case XIII: {
int mod52 = burstFN % 52;
if ((mod52 == 12) || (mod52 == 38))
- return cfg->ext_rach ? EXT_RACH : RACH;
+ return RACH; /* RACH is always 8-bit on PTCCH/U */
else if ((mod52 == 25) || (mod52 == 51))
return IDLE;
else /* Enable 8-PSK burst detection if EDGE is enabled */
@@ -619,6 +617,44 @@ double Transceiver::rssiOffset(size_t chan)
return mRadioInterface->rssiOffset(chan) + cfg->rssi_offset;
}
+static SoftVector *demodAnyBurst_va(const signalVector &burst, CorrType type, int sps, int rach_max_toa, int tsc)
+{
+ auto conved_beg = reinterpret_cast<const std::complex<float> *>(&burst.begin()[0]);
+ std::complex<float> chan_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR];
+ float ncmax;
+ const unsigned burst_len_bits = 148 + 8;
+ char demodded_softbits[burst_len_bits];
+ SoftVector *bits = new SoftVector(burst_len_bits);
+
+ if (type == CorrType::TSC) {
+ auto rach_burst_start = get_norm_chan_imp_resp(conved_beg, chan_imp_resp, &ncmax, tsc);
+ rach_burst_start = std::max(rach_burst_start, 0);
+ detect_burst_nb(conved_beg, chan_imp_resp, rach_burst_start, demodded_softbits);
+ } else {
+ auto normal_burst_start = get_access_imp_resp(conved_beg, chan_imp_resp, &ncmax, 0);
+ normal_burst_start = std::max(normal_burst_start, 0);
+ detect_burst_ab(conved_beg, chan_imp_resp, normal_burst_start, demodded_softbits, rach_max_toa);
+ }
+
+ float *s = &bits->begin()[0];
+ for (unsigned int i = 0; i < 148; i++)
+ s[i] = demodded_softbits[i] * -1;
+ for (unsigned int i = 148; i < burst_len_bits; i++)
+ s[i] = 0;
+ return bits;
+}
+
+#define USE_VA
+
+#ifdef USE_VA
+// signalvector is owning despite claiming not to, but we can pretend, too..
+static void dummy_free(void *wData){};
+static void *dummy_alloc(size_t newSize)
+{
+ return 0;
+};
+#endif
+
/*
* Pull bursts from the FIFO and handle according to the slot
* and burst correlation type. Equalzation is currently disabled.
@@ -639,6 +675,9 @@ int Transceiver::pullRadioVector(size_t chan, struct trx_ul_burst_ind *bi)
TransceiverState *state = &mStates[chan];
bool ctr_changed = false;
double rssi_offset;
+ static complex burst_shift_buffer[625];
+ static signalVector shift_vec(burst_shift_buffer, 0, 625, dummy_alloc, dummy_free);
+ signalVector *shvec_ptr = &shift_vec;
/* Blocking FIFO read */
radioVector *radio_burst = mReceiveFIFO[chan]->read();
@@ -648,7 +687,7 @@ int Transceiver::pullRadioVector(size_t chan, struct trx_ul_burst_ind *bi)
}
/* Set time and determine correlation type */
- burstTime = radio_burst->getTime();
+ burstTime = radio_burst->getTime() + cfg->ul_fn_offset;
CorrType type = expectedCorrType(burstTime, chan);
/* Initialize struct bi */
@@ -718,8 +757,15 @@ int Transceiver::pullRadioVector(size_t chan, struct trx_ul_burst_ind *bi)
max_toa = (type == RACH || type == EXT_RACH) ?
mMaxExpectedDelayAB : mMaxExpectedDelayNB;
+ if (cfg->use_va) {
+ // shifted burst copy to make the old demod and detection happy
+ std::copy(burst->begin() + 20, burst->end() - 20, shift_vec.begin());
+ } else {
+ shvec_ptr = burst;
+ }
+
/* Detect normal or RACH bursts */
- rc = detectAnyBurst(*burst, mTSC, BURST_THRESH, cfg->rx_sps, type, max_toa, &ebp);
+ rc = detectAnyBurst(*shvec_ptr, mTSC, BURST_THRESH, cfg->rx_sps, type, max_toa, &ebp);
if (rc <= 0) {
if (rc == -SIGERR_CLIP) {
LOGCHAN(chan, DTRXDUL, INFO) << "Clipping detected on received RACH or Normal Burst";
@@ -733,11 +779,16 @@ int Transceiver::pullRadioVector(size_t chan, struct trx_ul_burst_ind *bi)
goto ret_idle;
}
- type = (CorrType) rc;
+ if (cfg->use_va) {
+ scaleVector(*burst, { (1. / (float)((1 << 14) - 1)), 0 });
+ rxBurst = demodAnyBurst_va(*burst, (CorrType)rc, cfg->rx_sps, max_toa, mTSC);
+ } else {
+ rxBurst = demodAnyBurst(*shvec_ptr, (CorrType)rc, cfg->rx_sps, &ebp);
+ }
+
bi->toa = ebp.toa;
bi->tsc = ebp.tsc;
bi->ci = ebp.ci;
- rxBurst = demodAnyBurst(*burst, cfg->rx_sps, ebp.amp, ebp.toa, type);
/* EDGE demodulator returns 444 (gSlotLen * 3) bits */
if (rxBurst->size() == EDGE_BURST_NBITS) {
@@ -805,7 +856,7 @@ void Transceiver::ctrl_sock_send(ctrl_msg& m, int chan)
struct osmo_fd *conn_bfd = &s.conn_bfd;
s.txmsgqueue.push_back(m);
- conn_bfd->when |= OSMO_FD_WRITE;
+ osmo_fd_write_enable(conn_bfd);
}
int Transceiver::ctrl_sock_write(int chan)
@@ -820,7 +871,7 @@ int Transceiver::ctrl_sock_write(int chan)
while (s.txmsgqueue.size()) {
const ctrl_msg m = s.txmsgqueue.front();
- s.conn_bfd.when &= ~OSMO_FD_WRITE;
+ osmo_fd_write_disable(&s.conn_bfd);
/* try to send it over the socket */
rc = write(s.conn_bfd.fd, m.data, strlen(m.data) + 1);
@@ -828,7 +879,7 @@ int Transceiver::ctrl_sock_write(int chan)
goto close;
if (rc < 0) {
if (errno == EAGAIN) {
- s.conn_bfd.when |= OSMO_FD_WRITE;
+ osmo_fd_write_enable(&s.conn_bfd);
break;
}
goto close;
@@ -908,19 +959,18 @@ int Transceiver::ctrl_sock_handle_rx(int chan)
sprintf(response, "RSP NOHANDOVER 0 %u %u", ts, ss);
}
} else if (match_cmd(command, "SETMAXDLY", &params)) {
- //set expected maximum time-of-arrival
+ //set expected maximum time-of-arrival for Access Bursts
int maxDelay;
sscanf(params, "%d", &maxDelay);
mMaxExpectedDelayAB = maxDelay; // 1 GSM symbol is approx. 1 km
sprintf(response,"RSP SETMAXDLY 0 %d",maxDelay);
} else if (match_cmd(command, "SETMAXDLYNB", &params)) {
- //set expected maximum time-of-arrival
+ //set expected maximum time-of-arrival for Normal Bursts
int maxDelay;
sscanf(params, "%d", &maxDelay);
mMaxExpectedDelayNB = maxDelay; // 1 GSM symbol is approx. 1 km
sprintf(response,"RSP SETMAXDLYNB 0 %d",maxDelay);
} else if (match_cmd(command, "SETRXGAIN", &params)) {
- //set expected maximum time-of-arrival
int newGain;
sscanf(params, "%d", &newGain);
newGain = mRadioInterface->setRxGain(newGain, chan);
@@ -954,7 +1004,7 @@ int Transceiver::ctrl_sock_handle_rx(int chan)
// tune receiver
int freqKhz;
sscanf(params, "%d", &freqKhz);
- mRxFreq = freqKhz * 1e3;
+ mRxFreq = (freqKhz + cfg->freq_offset_khz) * 1e3;
if (!mRadioInterface->tuneRx(mRxFreq, chan)) {
LOGCHAN(chan, DTRXCTRL, FATAL) << "RX failed to tune";
sprintf(response,"RSP RXTUNE 1 %d",freqKhz);
@@ -965,7 +1015,7 @@ int Transceiver::ctrl_sock_handle_rx(int chan)
// tune txmtr
int freqKhz;
sscanf(params, "%d", &freqKhz);
- mTxFreq = freqKhz * 1e3;
+ mTxFreq = (freqKhz + cfg->freq_offset_khz) * 1e3;
if (!mRadioInterface->tuneTx(mTxFreq, chan)) {
LOGCHAN(chan, DTRXCTRL, FATAL) << "TX failed to tune";
sprintf(response,"RSP TXTUNE 1 %d",freqKhz);
@@ -1003,7 +1053,7 @@ int Transceiver::ctrl_sock_handle_rx(int chan)
LOGCHAN(chan, DTRXCTRL, INFO) << "BTS requests TRXD version switch: " << version_recv;
if (version_recv > TRX_DATA_FORMAT_VER) {
LOGCHAN(chan, DTRXCTRL, INFO) << "rejecting TRXD version " << version_recv
- << "in favor of " << TRX_DATA_FORMAT_VER;
+ << " in favor of " << TRX_DATA_FORMAT_VER;
sprintf(response, "RSP SETFORMAT %u %u", TRX_DATA_FORMAT_VER, version_recv);
} else {
LOGCHAN(chan, DTRXCTRL, NOTICE) << "switching to TRXD version " << version_recv;