diff options
-rw-r--r-- | Transceiver52M/Makefile.am | 3 | ||||
-rw-r--r-- | Transceiver52M/Transceiver.cpp | 42 | ||||
-rw-r--r-- | Transceiver52M/Transceiver.h | 14 | ||||
-rw-r--r-- | Transceiver52M/proto_trxd.c | 77 | ||||
-rw-r--r-- | Transceiver52M/proto_trxd.h | 48 |
5 files changed, 129 insertions, 55 deletions
diff --git a/Transceiver52M/Makefile.am b/Transceiver52M/Makefile.am index 4adf474..791c586 100644 --- a/Transceiver52M/Makefile.am +++ b/Transceiver52M/Makefile.am @@ -47,7 +47,8 @@ COMMON_SOURCES = \ Transceiver.cpp \ ChannelizerBase.cpp \ Channelizer.cpp \ - Synthesis.cpp + Synthesis.cpp \ + proto_trxd.c libtransceiver_common_la_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index 5c5707b..6bbf3a3 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -31,7 +31,7 @@ extern "C" { #include "osmo_signal.h" #include "proto_trxd.h" -#include <osmocom/core/bits.h> +#include <osmocom/core/utils.h> #include <osmocom/core/socket.h> } @@ -125,7 +125,7 @@ Transceiver::Transceiver(int wBasePort, rssiOffset(wRssiOffset), stackSize(wStackSize), mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans), mEdge(false), mOn(false), mForceClockInterface(false), mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(0), mMaxExpectedDelayNB(0), - mWriteBurstToDiskMask(0) + mWriteBurstToDiskMask(0), mVersionTRXD(0) { txFullScale = mRadioInterface->fullScaleInputValue(); rxFullScale = mRadioInterface->fullScaleOutputValue(); @@ -971,36 +971,20 @@ void Transceiver::logRxBurst(size_t chan, const struct trx_ul_burst_ind *bi) void Transceiver::driveReceiveFIFO(size_t chan) { - int msgLen; - int TOAint; // in 1/256 symbols - struct trx_ul_burst_ind bi; - if (!pullRadioVector(chan, &bi) || bi.idle) + if (!pullRadioVector(chan, &bi)) return; - - logRxBurst(chan, &bi); - - TOAint = (int) (bi.toa * 256.0 + 0.5); // round to closest integer - - char burstString[sizeof(struct trxd_hdr_v0) + bi.nbits + 2]; - struct trxd_hdr_v0* pkt = (struct trxd_hdr_v0*)burstString; - pkt->common.version = 0; - pkt->common.reserved = 0; - pkt->common.tn = bi.tn; - osmo_store32be(bi.fn, &pkt->common.fn); - pkt->v0.rssi = bi.rssi; - osmo_store16be(TOAint, &pkt->v0.toa); - - for (unsigned i = 0; i < bi.nbits; i++) - pkt->soft_bits[i] = (char) round(bi.rx_burst[i] * 255.0); - - /* +1: Historical reason. There's an uninitizalied byte in there: pkt->soft_bits[bi.nbits] */ - pkt->soft_bits[bi.nbits + 1] = '\0'; - - msgLen = write(mDataSockets[chan], burstString, sizeof(struct trxd_hdr_v0) + bi.nbits + 2); - if (msgLen <= 0) - LOGCHAN(chan, DTRXCTRL, WARNING) << "mDataSockets write(" << mCtrlSockets[chan] << ") failed: " << msgLen; + if (!bi.idle) + logRxBurst(chan, &bi); + + switch (mVersionTRXD) { + case 0: + trxd_send_burst_ind_v0(chan, mDataSockets[chan], &bi); + break; + default: + OSMO_ASSERT(false); + } } void Transceiver::driveTxFIFO() diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h index a66c962..aa2a716 100644 --- a/Transceiver52M/Transceiver.h +++ b/Transceiver52M/Transceiver.h @@ -34,19 +34,6 @@ extern "C" { #include "config_defs.h" } -#define MAX_RX_BURST_BUF_SIZE EDGE_BURST_NBITS - -struct trx_ul_burst_ind { - float rx_burst[MAX_RX_BURST_BUF_SIZE]; /* soft bits normalized 0..1 */ - unsigned nbits; // number of symbols per slot in rxBurst, not counting guard periods - uint32_t fn; // TDMA frame number - uint8_t tn; // TDMA time-slot number - double rssi; // in dBFS - double toa; // in symbols - double noise; // noise level in dBFS - bool idle; // true if no valid burst is included -}; - class Transceiver; /** Channel descriptor for transceiver object and channel number pair */ @@ -229,6 +216,7 @@ private: unsigned mMaxExpectedDelayAB; ///< maximum expected time-of-arrival offset in GSM symbols for Access Bursts (RACH) unsigned mMaxExpectedDelayNB; ///< maximum expected time-of-arrival offset in GSM symbols for Normal Bursts unsigned mWriteBurstToDiskMask; ///< debug: bitmask to indicate which timeslots to dump to disk + unsigned mVersionTRXD; ///< Format version to use for TRXD protocol communication std::vector<TransceiverState> mStates; diff --git a/Transceiver52M/proto_trxd.c b/Transceiver52M/proto_trxd.c new file mode 100644 index 0000000..5cf22e6 --- /dev/null +++ b/Transceiver52M/proto_trxd.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 sysmocom - s.f.m.c. GmbH + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * See the COPYING file in the main directory for details. + */ + +#include "proto_trxd.h" + +#include <osmocom/core/bits.h> + +static void trxd_fill_common(struct trxd_hdr_common *common, const struct trx_ul_burst_ind *bi, uint8_t version) +{ + common->version = version && 0x07; + common->reserved = 0; + common->tn = bi->tn; + osmo_store32be(bi->fn, &common->fn); +} + +static void trxd_fill_v0_specific(struct trxd_hdr_v0_specific *v0, const struct trx_ul_burst_ind *bi) +{ + int toa_int; + + /* in 1/256 symbols, round to closest integer */ + toa_int = (int) (bi->toa * 256.0 + 0.5); + v0->rssi = bi->rssi; + osmo_store16be(toa_int, &v0->toa); +} + +static void trxd_fill_burst_normalized255(uint8_t* soft_bits, const struct trx_ul_burst_ind *bi) +{ + unsigned i; + for (i = 0; i < bi->nbits; i++) + soft_bits[i] = (char) round(bi->rx_burst[i] * 255.0); +} + +bool trxd_send_burst_ind_v0(size_t chan, int fd, const struct trx_ul_burst_ind *bi) { + int rc; + + /* v0 doesn't support idle frames, they are simply dropped, not sent */ + if(bi->idle) + return true; + + /* +2: Historically (OpenBTS times), two extra non-used bytes are sent appeneded to each burst */ + char buf[sizeof(struct trxd_hdr_v0) + bi->nbits + 2]; + struct trxd_hdr_v0* pkt = (struct trxd_hdr_v0*)buf; + + trxd_fill_common(&pkt->common, bi, 0); + trxd_fill_v0_specific(&pkt->v0, bi); + trxd_fill_burst_normalized255(&pkt->soft_bits[0], bi); + + /* +1: Historical reason. There's an uninitizalied byte in there: pkt->soft_bits[bi->nbits] */ + pkt->soft_bits[bi->nbits + 1] = '\0'; + + rc = write(fd, buf, sizeof(struct trxd_hdr_v0) + bi->nbits + 2); + if (rc <= 0) { + CLOGCHAN(chan, DMAIN, LOGL_NOTICE, "mDataSockets write(%d) failed: %d\n", fd, rc); + return false; + } + return true; +} diff --git a/Transceiver52M/proto_trxd.h b/Transceiver52M/proto_trxd.h index 9da18db..2e5ad52 100644 --- a/Transceiver52M/proto_trxd.h +++ b/Transceiver52M/proto_trxd.h @@ -1,28 +1,52 @@ #pragma once #include <stdint.h> +#include <stdbool.h> +#include <unistd.h> +#include <math.h> + #include <osmocom/core/endian.h> +#include "debug.h" + +#define MAX_RX_BURST_BUF_SIZE 444 /* 444 = EDGE_BURST_NBITS */ + +struct trx_ul_burst_ind { + float rx_burst[MAX_RX_BURST_BUF_SIZE]; /* soft bits normalized 0..1 */ + unsigned nbits; // number of symbols per slot in rxBurst, not counting guard periods + uint32_t fn; // TDMA frame number + uint8_t tn; // TDMA time-slot number + double rssi; // in dBFS + double toa; // in symbols + double noise; // noise level in dBFS + bool idle; // true if no valid burst is included +}; + +bool trxd_send_burst_ind_v0(size_t chan, int fd, const struct trx_ul_burst_ind *bi); + +/* The latest supported TRXD header format version */ +#define TRX_DATA_FORMAT_VER 0 + struct trxd_hdr_common { #if OSMO_IS_LITTLE_ENDIAN - uint8_t tn:3, - reserved:1, - version:4; + uint8_t tn:3, + reserved:1, + version:4; #elif OSMO_IS_BIG_ENDIAN - uint8_t version:4, - reserved:1, - tn:3; + uint8_t version:4, + reserved:1, + tn:3; #endif - uint32_t fn; /* big endian */ + uint32_t fn; /* big endian */ } __attribute__ ((packed)); struct trxd_hdr_v0_specific { - uint8_t rssi; - uint16_t toa; /* big endian */ + uint8_t rssi; + uint16_t toa; /* big endian */ } __attribute__ ((packed)); struct trxd_hdr_v0 { - struct trxd_hdr_common common; - struct trxd_hdr_v0_specific v0; - uint8_t soft_bits[0]; + struct trxd_hdr_common common; + struct trxd_hdr_v0_specific v0; + uint8_t soft_bits[0]; } __attribute__ ((packed)); |