diff options
Diffstat (limited to 'Transceiver52M/Transceiver.cpp')
-rw-r--r-- | Transceiver52M/Transceiver.cpp | 104 |
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", ¶ms)) { - //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", ¶ms)) { - //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", ¶ms)) { - //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; |