mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
synced 2025-11-02 13:13:17 +00:00
Compare commits
15 Commits
fairwaves/
...
max/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f38a0c06dc | ||
|
|
3b093bb13b | ||
|
|
3f4a13f049 | ||
|
|
0fe41a583c | ||
|
|
a5e0f1cdba | ||
|
|
2c650a6895 | ||
|
|
d4555f267e | ||
|
|
047956259b | ||
|
|
d2b070369d | ||
|
|
9664c3a6e7 | ||
|
|
1ab5e7f7bc | ||
|
|
5efe05021a | ||
|
|
78d1fc9a13 | ||
|
|
a8cf208616 | ||
|
|
f84232d30a |
56
.gitignore
vendored
Normal file
56
.gitignore
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
CommonLibs/BitVectorTest
|
||||
CommonLibs/ConfigurationTest
|
||||
CommonLibs/F16Test
|
||||
CommonLibs/InterthreadTest
|
||||
CommonLibs/LogTest
|
||||
CommonLibs/Makefile
|
||||
CommonLibs/Makefile.in
|
||||
CommonLibs/RegexpTest
|
||||
CommonLibs/SocketsTest
|
||||
CommonLibs/TimevalTest
|
||||
CommonLibs/URLEncodeTest
|
||||
CommonLibs/VectorTest
|
||||
CommonLibs/libcommon.la
|
||||
GSM/Makefile
|
||||
GSM/Makefile.in
|
||||
GSM/libGSM.la
|
||||
Makefile
|
||||
Makefile.in
|
||||
Transceiver52M/Makefile
|
||||
Transceiver52M/Makefile.in
|
||||
Transceiver52M/arm/Makefile
|
||||
Transceiver52M/arm/Makefile.in
|
||||
Transceiver52M/common/.dirstamp
|
||||
Transceiver52M/libtransceiver.la
|
||||
Transceiver52M/osmo-trx
|
||||
Transceiver52M/x86/Makefile
|
||||
Transceiver52M/x86/Makefile.in
|
||||
Transceiver52M/x86/libarch.la
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
config/libtool.m4
|
||||
config/ltoptions.m4
|
||||
config/ltsugar.m4
|
||||
config/ltversion.m4
|
||||
config/lt~obsolete.m4
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
sqlite3/Makefile
|
||||
sqlite3/Makefile.in
|
||||
sqlite3/libsqlite.la
|
||||
stamp-h1
|
||||
@@ -187,24 +187,20 @@ int DatagramSocket::send(const struct sockaddr* dest, const char * message)
|
||||
return send(dest,message,length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int DatagramSocket::read(char* buffer)
|
||||
int DatagramSocket::read(char* buffer, size_t length)
|
||||
{
|
||||
socklen_t temp_len = sizeof(mSource);
|
||||
int length = recvfrom(mSocketFD, (void*)buffer, MAX_UDP_LENGTH, 0,
|
||||
(struct sockaddr*)&mSource,&temp_len);
|
||||
if ((length==-1) && (errno!=EAGAIN)) {
|
||||
socklen_t addr_len = sizeof(mSource);
|
||||
int rd_length = recvfrom(mSocketFD, (void *) buffer, length, 0,
|
||||
(struct sockaddr*) &mSource, &addr_len);
|
||||
|
||||
if ((rd_length==-1) && (errno!=EAGAIN)) {
|
||||
perror("DatagramSocket::read() failed");
|
||||
throw SocketError();
|
||||
}
|
||||
return length;
|
||||
return rd_length;
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::read(char* buffer, unsigned timeout)
|
||||
int DatagramSocket::read(char* buffer, size_t length, unsigned timeout)
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
@@ -218,7 +214,7 @@ int DatagramSocket::read(char* buffer, unsigned timeout)
|
||||
throw SocketError();
|
||||
}
|
||||
if (sel==0) return -1;
|
||||
if (FD_ISSET(mSocketFD,&fds)) return read(buffer);
|
||||
if (FD_ISSET(mSocketFD,&fds)) return read(buffer, length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -269,7 +265,7 @@ void UDPSocket::open(unsigned short localPort)
|
||||
size_t length = sizeof(address);
|
||||
bzero(&address,length);
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
address.sin_port = htons(localPort);
|
||||
if (bind(mSocketFD,(struct sockaddr*)&address,length)<0) {
|
||||
perror("bind() failed");
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
@param buffer A char[MAX_UDP_LENGTH] procured by the caller.
|
||||
@return The number of bytes received or -1 on non-blocking pass.
|
||||
*/
|
||||
int read(char* buffer);
|
||||
int read(char* buffer, size_t length);
|
||||
|
||||
/**
|
||||
Receive a packet with a timeout.
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
@param maximum wait time in milliseconds
|
||||
@return The number of bytes received or -1 on timeout.
|
||||
*/
|
||||
int read(char* buffer, unsigned timeout);
|
||||
int read(char* buffer, size_t length, unsigned timeout);
|
||||
|
||||
|
||||
/** Send a packet to a given destination, other than the default. */
|
||||
|
||||
@@ -42,7 +42,7 @@ void *testReaderIP(void *)
|
||||
int rc = 0;
|
||||
while (rc<gNumToSend) {
|
||||
char buf[MAX_UDP_LENGTH];
|
||||
int count = readSocket.read(buf);
|
||||
int count = readSocket.read(buf, MAX_UDP_LENGTH);
|
||||
if (count>0) {
|
||||
COUT("read: " << buf);
|
||||
rc++;
|
||||
@@ -62,7 +62,7 @@ void *testReaderUnix(void *)
|
||||
int rc = 0;
|
||||
while (rc<gNumToSend) {
|
||||
char buf[MAX_UDP_LENGTH];
|
||||
int count = readSocket.read(buf);
|
||||
int count = readSocket.read(buf, MAX_UDP_LENGTH);
|
||||
if (count>0) {
|
||||
COUT("read: " << buf);
|
||||
rc++;
|
||||
|
||||
@@ -71,7 +71,7 @@ TransceiverState::~TransceiverState()
|
||||
}
|
||||
}
|
||||
|
||||
bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc, unsigned rach_delay)
|
||||
bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc)
|
||||
{
|
||||
signalVector *burst;
|
||||
|
||||
@@ -91,7 +91,7 @@ bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc, un
|
||||
burst = generateEdgeBurst(rtsc);
|
||||
break;
|
||||
case Transceiver::FILLER_ACCESS_RAND:
|
||||
burst = genRandAccessBurst(rach_delay, sps, n);
|
||||
burst = genRandAccessBurst(sps, n);
|
||||
break;
|
||||
case Transceiver::FILLER_ZERO:
|
||||
default:
|
||||
@@ -122,7 +122,7 @@ Transceiver::Transceiver(int wBasePort,
|
||||
mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
|
||||
rssiOffset(wRssiOffset),
|
||||
mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans), mOn(false),
|
||||
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(2*rx_sps), mMaxExpectedDelayNB(2*rx_sps),
|
||||
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelayAB(0), mMaxExpectedDelayNB(0),
|
||||
mWriteBurstToDiskMask(0)
|
||||
{
|
||||
txFullScale = mRadioInterface->fullScaleInputValue();
|
||||
@@ -160,7 +160,7 @@ Transceiver::~Transceiver()
|
||||
* are still expected to report clock indications through control channel
|
||||
* activity.
|
||||
*/
|
||||
bool Transceiver::init(int filler, size_t rtsc, unsigned rach_delay)
|
||||
bool Transceiver::init(int filler, size_t rtsc)
|
||||
{
|
||||
int d_srcport, d_dstport, c_srcport, c_dstport;
|
||||
|
||||
@@ -216,7 +216,7 @@ bool Transceiver::init(int filler, size_t rtsc, unsigned rach_delay)
|
||||
if (i && filler == FILLER_DUMMY)
|
||||
filler = FILLER_ZERO;
|
||||
|
||||
mStates[i].init(filler, mSPSTx, txFullScale, rtsc, rach_delay);
|
||||
mStates[i].init(filler, mSPSTx, txFullScale, rtsc);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -531,8 +531,8 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
|
||||
}
|
||||
}
|
||||
|
||||
int Transceiver::detectBurst(TransceiverState *state, signalVector &burst,
|
||||
complex &, float &toa, CorrType type)
|
||||
int Transceiver::detectBurst(signalVector &burst,
|
||||
complex &, float &toa, CorrType type)
|
||||
{
|
||||
float threshold = 5.0, rc = 0;
|
||||
|
||||
@@ -567,8 +567,7 @@ int Transceiver::detectBurst(TransceiverState *state, signalVector &burst,
|
||||
/*
|
||||
* Demodulate GMSK by direct rotation and soft slicing.
|
||||
*/
|
||||
SoftVector *Transceiver::demodulate(TransceiverState *state,
|
||||
signalVector &burst, complex amp,
|
||||
SoftVector *Transceiver::demodulate(signalVector &burst, complex amp,
|
||||
float toa, CorrType type)
|
||||
{
|
||||
if (type == EDGE)
|
||||
@@ -666,7 +665,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i
|
||||
}
|
||||
|
||||
/* Detect normal or RACH bursts */
|
||||
rc = detectBurst(state, *burst, amp, toa, type);
|
||||
rc = detectBurst(*burst, amp, toa, type);
|
||||
|
||||
if (rc > 0) {
|
||||
type = (CorrType) rc;
|
||||
@@ -683,7 +682,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i
|
||||
|
||||
timingOffset = toa / mSPSRx;
|
||||
|
||||
bits = demodulate(state, *burst, amp, toa, type);
|
||||
bits = demodulate(*burst, amp, toa, type);
|
||||
|
||||
delete radio_burst;
|
||||
return bits;
|
||||
@@ -705,7 +704,7 @@ void Transceiver::driveControl(size_t chan)
|
||||
int msgLen = -1;
|
||||
buffer[0] = '\0';
|
||||
|
||||
msgLen = mCtrlSockets[chan]->read(buffer);
|
||||
msgLen = mCtrlSockets[chan]->read(buffer, sizeof(buffer));
|
||||
|
||||
if (msgLen < 1) {
|
||||
return;
|
||||
@@ -873,7 +872,7 @@ bool Transceiver::driveTxPriorityQueue(size_t chan)
|
||||
char buffer[gSlotLen+50];
|
||||
|
||||
// check data socket
|
||||
size_t msgLen = mDataSockets[chan]->read(buffer);
|
||||
size_t msgLen = mDataSockets[chan]->read(buffer, sizeof(buffer));
|
||||
|
||||
if (msgLen!=gSlotLen+1+4+1) {
|
||||
LOG(ERR) << "badly formatted packet on GSM->TRX interface";
|
||||
@@ -913,11 +912,10 @@ void Transceiver::driveReceiveRadio()
|
||||
}
|
||||
}
|
||||
|
||||
void Transceiver::logRxBurst(size_t chan, SoftVector *burst, GSM::Time time, double dbm,
|
||||
void Transceiver::logRxBurst(SoftVector *burst, GSM::Time time, double dbm,
|
||||
double rssi, double noise, double toa)
|
||||
{
|
||||
LOG(DEBUG) << std::fixed << std::right
|
||||
<< " chan: " << chan
|
||||
<< " time: " << time
|
||||
<< " RSSI: " << std::setw(5) << std::setprecision(1) << rssi
|
||||
<< "dBFS/" << std::setw(6) << -dbm << "dBm"
|
||||
@@ -950,7 +948,7 @@ void Transceiver::driveReceiveFIFO(size_t chan)
|
||||
nbits = gSlotLen * 3;
|
||||
|
||||
dBm = RSSI + rssiOffset;
|
||||
logRxBurst(chan, rxBurst, burstTime, dBm, RSSI, noise, TOA);
|
||||
logRxBurst(rxBurst, burstTime, dBm, RSSI, noise, TOA);
|
||||
|
||||
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ struct TransceiverState {
|
||||
~TransceiverState();
|
||||
|
||||
/* Initialize a multiframe slot in the filler table */
|
||||
bool init(int filler, size_t sps, float scale, size_t rtsc, unsigned rach_delay);
|
||||
bool init(int filler, size_t sps, float scale, size_t rtsc);
|
||||
|
||||
int chanType[8];
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
~Transceiver();
|
||||
|
||||
/** Start the control loop */
|
||||
bool init(int filler, size_t rtsc, unsigned rach_delay);
|
||||
bool init(int filler, size_t rtsc);
|
||||
|
||||
/** attach the radioInterface receive FIFO */
|
||||
bool receiveFIFO(VectorFIFO *wFIFO, size_t chan)
|
||||
@@ -212,11 +212,11 @@ private:
|
||||
void writeClockInterface(void);
|
||||
|
||||
/** Detectbursts */
|
||||
int detectBurst(TransceiverState *state, signalVector &burst,
|
||||
int detectBurst(signalVector &burst,
|
||||
complex &, float &toa, CorrType type);
|
||||
|
||||
/** Demodulate burst and output soft bits */
|
||||
SoftVector *demodulate(TransceiverState *state, signalVector &burst,
|
||||
SoftVector *demodulate(signalVector &burst,
|
||||
complex amp, float toa, CorrType type);
|
||||
|
||||
int mSPSTx; ///< number of samples per Tx symbol
|
||||
@@ -276,7 +276,7 @@ protected:
|
||||
/** set priority on current thread */
|
||||
void setPriority(float prio = 0.5) { mRadioInterface->setPriority(prio); }
|
||||
|
||||
void logRxBurst(size_t chan, SoftVector *burst, GSM::Time time, double dbm,
|
||||
void logRxBurst(SoftVector *burst, GSM::Time time, double dbm,
|
||||
double rssi, double noise, double toa);
|
||||
};
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ enum uhd_dev_type {
|
||||
|
||||
struct uhd_dev_offset {
|
||||
enum uhd_dev_type type;
|
||||
int tx_sps;
|
||||
int rx_sps;
|
||||
size_t tx_sps;
|
||||
size_t rx_sps;
|
||||
double offset;
|
||||
const std::string desc;
|
||||
};
|
||||
@@ -80,11 +80,11 @@ struct uhd_dev_offset {
|
||||
#ifdef USE_UHD_3_9
|
||||
#define B2XX_TIMING_1SPS 1.7153e-4
|
||||
#define B2XX_TIMING_4SPS 1.1696e-4
|
||||
#define B2XX_TIMING_4_4SPS 5.89578e-5
|
||||
#define B2XX_TIMING_4_4SPS 6.18462e-5
|
||||
#else
|
||||
#define B2XX_TIMING_1SPS 9.9692e-5
|
||||
#define B2XX_TIMING_4SPS 6.9248e-5
|
||||
#define B2XX_TIMING_4_4SPS 4.19034e-5
|
||||
#define B2XX_TIMING_4_4SPS 4.52308e-5
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -110,8 +110,8 @@ static struct uhd_dev_offset uhd_offsets[] = {
|
||||
{ B210, 4, 1, B2XX_TIMING_4SPS, "B210 4 SPS" },
|
||||
{ E1XX, 1, 1, 9.5192e-5, "E1XX 1 SPS" },
|
||||
{ E1XX, 4, 1, 6.5571e-5, "E1XX 4 SPS" },
|
||||
{ E3XX, 1, 1, 1.5000e-4, "E3XX 1 SPS" },
|
||||
{ E3XX, 4, 1, 1.2740e-4, "E3XX 4 SPS" },
|
||||
{ E3XX, 1, 1, 1.84616e-4, "E3XX 1 SPS" },
|
||||
{ E3XX, 4, 1, 1.29231e-4, "E3XX 4 SPS" },
|
||||
{ X3XX, 1, 1, 1.5360e-4, "X3XX 1 SPS"},
|
||||
{ X3XX, 4, 1, 1.1264e-4, "X3XX 4 SPS"},
|
||||
{ UMTRX, 1, 1, 9.9692e-5, "UmTRX 1 SPS" },
|
||||
@@ -131,63 +131,6 @@ static struct uhd_dev_offset special_offsets[] = {
|
||||
{ UMTRX, 4, 1, 5.2103e-5, "UmTRX diversity, 4 SPS" },
|
||||
};
|
||||
|
||||
static double get_dev_offset(enum uhd_dev_type type, int tx_sps, int rx_sps,
|
||||
bool edge = false, bool diversity = false)
|
||||
{
|
||||
struct uhd_dev_offset *offset = NULL;
|
||||
|
||||
/* Reject USRP1 */
|
||||
if (type == USRP1) {
|
||||
LOG(ERR) << "Invalid device type";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (edge && diversity) {
|
||||
LOG(ERR) << "Unsupported configuration";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (edge && (type != B200) && (type != B210) && (type != UMTRX)) {
|
||||
LOG(ALERT) << "EDGE is supported on B200/B210 and UmTRX only";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* Special cases (e.g. diversity receiver) */
|
||||
if (diversity) {
|
||||
if (type != UMTRX) {
|
||||
LOG(ALERT) << "Diversity on UmTRX only";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
switch (tx_sps) {
|
||||
case 1:
|
||||
offset = &special_offsets[0];
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
offset = &special_offsets[1];
|
||||
}
|
||||
} else {
|
||||
/* Search for matching offset value */
|
||||
for (size_t i = 0; i < NUM_UHD_OFFSETS; i++) {
|
||||
if ((type == uhd_offsets[i].type) &&
|
||||
(tx_sps == uhd_offsets[i].tx_sps) &&
|
||||
(rx_sps == uhd_offsets[i].rx_sps)) {
|
||||
offset = &uhd_offsets[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!offset) {
|
||||
LOG(ERR) << "Invalid device configuration";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
std::cout << "-- Setting " << offset->desc << std::endl;
|
||||
|
||||
return offset->offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select sample rate based on device type and requested samples-per-symbol.
|
||||
@@ -385,6 +328,7 @@ private:
|
||||
std::vector<smpl_buf *> rx_buffers;
|
||||
|
||||
void init_gains();
|
||||
double get_dev_offset(bool edge, bool diversity);
|
||||
int set_master_clk(double rate);
|
||||
int set_rates(double tx_rate, double rx_rate);
|
||||
bool parse_dev_type();
|
||||
@@ -513,6 +457,64 @@ void uhd_device::init_gains()
|
||||
|
||||
}
|
||||
|
||||
double uhd_device::get_dev_offset(bool edge, bool diversity)
|
||||
{
|
||||
struct uhd_dev_offset *offset = NULL;
|
||||
|
||||
/* Reject USRP1 */
|
||||
if (dev_type == USRP1) {
|
||||
LOG(ERR) << "Invalid device type";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (edge && diversity) {
|
||||
LOG(ERR) << "Unsupported configuration";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (edge && (dev_type != B200) &&
|
||||
(dev_type != B210) && (dev_type != UMTRX)) {
|
||||
LOG(ALERT) << "EDGE is supported on B200/B210 and UmTRX only";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* Special cases (e.g. diversity receiver) */
|
||||
if (diversity) {
|
||||
if (dev_type != UMTRX) {
|
||||
LOG(ALERT) << "Diversity on UmTRX only";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
switch (tx_sps) {
|
||||
case 1:
|
||||
offset = &special_offsets[0];
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
offset = &special_offsets[1];
|
||||
}
|
||||
} else {
|
||||
/* Search for matching offset value */
|
||||
for (size_t i = 0; i < NUM_UHD_OFFSETS; i++) {
|
||||
if ((dev_type == uhd_offsets[i].type) &&
|
||||
(tx_sps == uhd_offsets[i].tx_sps) &&
|
||||
(rx_sps == uhd_offsets[i].rx_sps)) {
|
||||
offset = &uhd_offsets[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!offset) {
|
||||
LOG(ERR) << "Invalid device configuration";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
std::cout << "-- Setting " << offset->desc << std::endl;
|
||||
|
||||
return offset->offset;
|
||||
}
|
||||
|
||||
int uhd_device::set_master_clk(double clk_rate)
|
||||
{
|
||||
double actual, offset, limit = 1.0;
|
||||
@@ -643,7 +645,7 @@ bool uhd_device::parse_dev_type()
|
||||
{
|
||||
std::string mboard_str, dev_str;
|
||||
uhd::property_tree::sptr prop_tree;
|
||||
size_t usrp1_str, usrp2_str, e100_str, e110_str, e310_str,
|
||||
size_t usrp1_str, usrp2_str, e100_str, e110_str, e310_str, e3xx_str,
|
||||
b100_str, b200_str, b210_str, x300_str, x310_str, umtrx_str;
|
||||
|
||||
prop_tree = usrp_dev->get_device()->get_tree();
|
||||
@@ -658,6 +660,7 @@ bool uhd_device::parse_dev_type()
|
||||
e100_str = mboard_str.find("E100");
|
||||
e110_str = mboard_str.find("E110");
|
||||
e310_str = mboard_str.find("E310");
|
||||
e3xx_str = mboard_str.find("E3XX");
|
||||
x300_str = mboard_str.find("X300");
|
||||
x310_str = mboard_str.find("X310");
|
||||
umtrx_str = dev_str.find("UmTRX");
|
||||
@@ -687,7 +690,8 @@ bool uhd_device::parse_dev_type()
|
||||
} else if (usrp2_str != std::string::npos) {
|
||||
tx_window = TX_WINDOW_FIXED;
|
||||
dev_type = USRP2;
|
||||
} else if (e310_str != std::string::npos) {
|
||||
} else if ((e310_str != std::string::npos) ||
|
||||
(e3xx_str != std::string::npos)) {
|
||||
tx_window = TX_WINDOW_FIXED;
|
||||
dev_type = E3XX;
|
||||
} else if (x300_str != std::string::npos) {
|
||||
@@ -700,7 +704,8 @@ bool uhd_device::parse_dev_type()
|
||||
tx_window = TX_WINDOW_FIXED;
|
||||
dev_type = UMTRX;
|
||||
} else {
|
||||
LOG(ALERT) << "Unknown UHD device type " << dev_str;
|
||||
LOG(ALERT) << "Unknown UHD device type "
|
||||
<< dev_str << " " << mboard_str;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -715,6 +720,26 @@ bool uhd_device::parse_dev_type()
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for UHD version > 3.9.0 for E3XX support
|
||||
*/
|
||||
static bool uhd_e3xx_version_chk()
|
||||
{
|
||||
std::string ver = uhd::get_version_string();
|
||||
std::string major_str(ver.begin(), ver.begin() + 3);
|
||||
std::string minor_str(ver.begin() + 4, ver.begin() + 7);
|
||||
|
||||
int major_val = atoi(major_str.c_str());
|
||||
int minor_val = atoi(minor_str.c_str());
|
||||
|
||||
if (major_val < 3)
|
||||
return false;
|
||||
if (minor_val < 9)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
|
||||
{
|
||||
// Find UHD devices
|
||||
@@ -738,6 +763,11 @@ int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
|
||||
if (!parse_dev_type())
|
||||
return -1;
|
||||
|
||||
if ((dev_type == E3XX) && !uhd_e3xx_version_chk()) {
|
||||
LOG(ALERT) << "E3XX requires UHD 003.009.000 or greater";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Verify and set channels
|
||||
if ((dev_type == B210) && (chans == 2)) {
|
||||
} else if ((dev_type == UMTRX) && (chans == 2)) {
|
||||
@@ -801,7 +831,7 @@ int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
|
||||
if (rx_sps == 4)
|
||||
edge = true;
|
||||
|
||||
double offset = get_dev_offset(dev_type, tx_sps, rx_sps, edge, diversity);
|
||||
double offset = get_dev_offset(edge, diversity);
|
||||
if (offset == 0.0) {
|
||||
LOG(ERR) << "Unsupported configuration, no correction applied";
|
||||
ts_offset = 0;
|
||||
|
||||
@@ -37,14 +37,9 @@
|
||||
* 1 - Uses minimized modulator (less computation, more distortion)
|
||||
*
|
||||
* Other values are invalid. Receive path (uplink) is always
|
||||
* downsampled to 1 sps. Default to 4 sps for all cases except for
|
||||
* ARM and non-SIMD enabled architectures.
|
||||
* downsampled to 1 sps. Default to 4 sps for all cases.
|
||||
*/
|
||||
#if defined(HAVE_NEON) || !defined(HAVE_SSE3)
|
||||
#define DEFAULT_TX_SPS 1
|
||||
#else
|
||||
#define DEFAULT_TX_SPS 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Samples-per-symbol for uplink (receiver) path
|
||||
@@ -75,7 +70,6 @@ struct trx_config {
|
||||
unsigned rx_sps;
|
||||
unsigned chans;
|
||||
unsigned rtsc;
|
||||
unsigned rach_delay;
|
||||
bool extref;
|
||||
Transceiver::FillerType filler;
|
||||
bool diversity;
|
||||
@@ -201,6 +195,7 @@ bool trx_setup_config(struct trx_config *config)
|
||||
ost << " TRX Address............. " << config->addr << std::endl;
|
||||
ost << " Channels................ " << config->chans << std::endl;
|
||||
ost << " Tx Samples-per-Symbol... " << config->tx_sps << std::endl;
|
||||
ost << " Rx Samples-per-Symbol... " << config->rx_sps << std::endl;
|
||||
ost << " EDGE support............ " << edgestr << std::endl;
|
||||
ost << " External Reference...... " << refstr << std::endl;
|
||||
ost << " C0 Filler Table......... " << fillstr << std::endl;
|
||||
@@ -270,7 +265,7 @@ Transceiver *makeTransceiver(struct trx_config *config, RadioInterface *radio)
|
||||
trx = new Transceiver(config->port, config->addr.c_str(),
|
||||
config->tx_sps, config->rx_sps, config->chans,
|
||||
GSM::Time(3,0), radio, config->rssi_offset);
|
||||
if (!trx->init(config->filler, config->rtsc, config->rach_delay)) {
|
||||
if (!trx->init(config->filler, config->rtsc)) {
|
||||
LOG(ALERT) << "Failed to initialize transceiver";
|
||||
delete trx;
|
||||
return NULL;
|
||||
@@ -322,8 +317,8 @@ 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 Normal Burst test mode with TSC\n"
|
||||
" -A Random Access Burst test mode with delay\n"
|
||||
" -r Random burst test mode with TSC\n"
|
||||
" -A Random burst test mode with Access Bursts\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");
|
||||
@@ -338,7 +333,6 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
config->rx_sps = DEFAULT_RX_SPS;
|
||||
config->chans = DEFAULT_CHANS;
|
||||
config->rtsc = 0;
|
||||
config->rach_delay = 0;
|
||||
config->extref = false;
|
||||
config->filler = Transceiver::FILLER_ZERO;
|
||||
config->diversity = false;
|
||||
@@ -347,7 +341,7 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
config->swap_channels = false;
|
||||
config->edge = false;
|
||||
|
||||
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:A:R:Se")) != -1) {
|
||||
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:AR:Se")) != -1) {
|
||||
switch (option) {
|
||||
case 'h':
|
||||
print_help();
|
||||
@@ -388,7 +382,6 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
config->filler = Transceiver::FILLER_NORM_RAND;
|
||||
break;
|
||||
case 'A':
|
||||
config->rach_delay = atoi(optarg);
|
||||
config->filler = Transceiver::FILLER_ACCESS_RAND;
|
||||
break;
|
||||
case 'R':
|
||||
@@ -427,12 +420,6 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
print_help();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (config->rach_delay > 68) {
|
||||
printf("RACH delay is too big %i\n\n", config->rach_delay);
|
||||
print_help();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
@@ -935,26 +935,35 @@ static signalVector *mapEdgeSymbols(const BitVector &bits)
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/*
|
||||
* EDGE 8-PSK rotate and pulse shape
|
||||
*
|
||||
* Delay the EDGE downlink bursts by one symbol in order to match GMSK pulse
|
||||
* shaping group delay. The difference in group delay arises from the dual
|
||||
* pulse filter combination of the GMSK Laurent represenation whereas 8-PSK
|
||||
* uses a single pulse linear filter.
|
||||
*/
|
||||
static signalVector *shapeEdgeBurst(const signalVector &symbols)
|
||||
{
|
||||
size_t nsyms, nsamps = 625;
|
||||
size_t nsyms, nsamps = 625, sps = 4;
|
||||
signalVector *burst, *shape;
|
||||
signalVector::iterator burst_itr;
|
||||
|
||||
nsyms = symbols.size();
|
||||
|
||||
if (nsyms * 4 > nsamps)
|
||||
if (nsyms * sps > nsamps)
|
||||
nsyms = 156;
|
||||
|
||||
burst = new signalVector(nsamps, GSMPulse4->c0->size());
|
||||
burst_itr = burst->begin();
|
||||
|
||||
for (size_t i = 0; i < nsyms; i++) {
|
||||
/* Delay burst by 1 symbol */
|
||||
burst_itr = burst->begin() + sps;
|
||||
for (size_t i = 0; i < nsyms - 1; i++) {
|
||||
float phase = i * 3.0f * M_PI / 8.0f;
|
||||
Complex<float> rot = Complex<float>(cos(phase), sin(phase));
|
||||
|
||||
*burst_itr = symbols[i] * rot;
|
||||
burst_itr += 4;
|
||||
burst_itr += sps;
|
||||
}
|
||||
|
||||
/* Single Gaussian pulse approximation shaping */
|
||||
@@ -1008,36 +1017,30 @@ signalVector *genRandNormalBurst(int tsc, int sps, int tn)
|
||||
/*
|
||||
* Generate a random GSM access burst.
|
||||
*/
|
||||
signalVector *genRandAccessBurst(int delay, int sps, int tn)
|
||||
signalVector *genRandAccessBurst(int sps, int tn)
|
||||
{
|
||||
if ((tn < 0) || (tn > 7))
|
||||
return NULL;
|
||||
if ((sps != 1) && (sps != 4))
|
||||
return NULL;
|
||||
if (delay > 68)
|
||||
return NULL;
|
||||
|
||||
int i = 0;
|
||||
BitVector *bits = new BitVector(88+delay);
|
||||
BitVector *bits = new BitVector(88);
|
||||
signalVector *burst;
|
||||
|
||||
/* delay */
|
||||
for (; i < delay; i++)
|
||||
(*bits)[i] = 0;
|
||||
|
||||
/* head and synch bits */
|
||||
for (int n = 0; i < 49+delay; i++, n++)
|
||||
for (int n = 0; i < 49; i++, n++)
|
||||
(*bits)[i] = gRACHBurst[n];
|
||||
|
||||
/* Random bits */
|
||||
for (; i < 85+delay; i++)
|
||||
for (; i < 85; i++)
|
||||
(*bits)[i] = rand() % 2;
|
||||
|
||||
/* Tail bits */
|
||||
for (; i < 88+delay; i++)
|
||||
for (; i < 88; i++)
|
||||
(*bits)[i] = 0;
|
||||
|
||||
int guard = 68-delay + !(tn % 4);
|
||||
int guard = 68 + !(tn % 4);
|
||||
burst = modulateBurst(*bits, guard, sps);
|
||||
delete bits;
|
||||
|
||||
@@ -1855,7 +1858,7 @@ int detectGeneralBurst(signalVector &rxBurst,
|
||||
*
|
||||
* Correlation window parameters:
|
||||
* target: Tail bits + RACH length (reduced from 41 to a multiple of 4)
|
||||
* head: Search 8 symbols before target
|
||||
* head: Search 4 symbols before target
|
||||
* tail: Search 4 symbols + maximum expected delay
|
||||
*/
|
||||
int detectRACHBurst(signalVector &rxBurst,
|
||||
@@ -1869,7 +1872,7 @@ int detectRACHBurst(signalVector &rxBurst,
|
||||
CorrelationSequence *sync;
|
||||
|
||||
target = 8 + 40;
|
||||
head = 8;
|
||||
head = 4;
|
||||
tail = 4 + maxTOA;
|
||||
sync = gRACHSequence;
|
||||
|
||||
@@ -2086,7 +2089,7 @@ SoftVector *demodEdgeBurst(signalVector &burst, int sps,
|
||||
rot = derotateEdgeBurst(*eq, 1);
|
||||
|
||||
/* Soft slice and normalize */
|
||||
bits = softSliceEdgeBurst(*dec);
|
||||
bits = softSliceEdgeBurst(*rot);
|
||||
vectorSlicer(bits);
|
||||
|
||||
delete dec;
|
||||
|
||||
@@ -123,7 +123,7 @@ signalVector *generateEmptyBurst(int sps, int tn);
|
||||
signalVector *genRandNormalBurst(int tsc, int sps, int tn);
|
||||
|
||||
/** Generate an access GSM burst with random payload - 4 or 1 SPS */
|
||||
signalVector *genRandAccessBurst(int delay, int sps, int tn);
|
||||
signalVector *genRandAccessBurst(int sps, int tn);
|
||||
|
||||
/** Generate a dummy GSM burst - 4 or 1 SPS */
|
||||
signalVector *generateDummyBurst(int sps, int tn);
|
||||
|
||||
7
debian/changelog
vendored
7
debian/changelog
vendored
@@ -1,10 +1,3 @@
|
||||
osmo-trx (0.1.10~1) trusty; urgency=medium
|
||||
|
||||
* some EDGE support in master
|
||||
* fairwaves/rach-filler branch
|
||||
|
||||
-- Kirill Zakharenko <earwin@gmail.com> Sun, 27 Mar 2016 19:37:39 +0100
|
||||
|
||||
osmo-trx (0.1.9) trusty; urgency=medium
|
||||
|
||||
* Ask Ivan, really
|
||||
|
||||
3
debian/rules
vendored
3
debian/rules
vendored
@@ -5,9 +5,6 @@ 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user