mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
synced 2025-11-02 05:03:18 +00:00
Compare commits
20 Commits
Hoernchen/
...
fairwaves/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8f000cca1 | ||
|
|
f1c1379e97 | ||
|
|
bb7b057ec3 | ||
|
|
9155d8da94 | ||
|
|
8b8e7ecf8a | ||
|
|
e587cdb213 | ||
|
|
5d1eaaffcc | ||
|
|
511a662394 | ||
|
|
7d2866164b | ||
|
|
a0f8ed8ecb | ||
|
|
c579c071f4 | ||
|
|
2337e8f8aa | ||
|
|
afa28be3ef | ||
|
|
cab15655f3 | ||
|
|
f8e8e57568 | ||
|
|
441dd35a6f | ||
|
|
bf7ed547ac | ||
|
|
ab31d70678 | ||
|
|
341869feb1 | ||
|
|
31862c5e4c |
@@ -35,7 +35,7 @@
|
||||
#ifdef DEBUG_CONFIG
|
||||
#define debugLogEarly gLogEarly
|
||||
#else
|
||||
#define debugLogEarly
|
||||
#define debugLogEarly(x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,14 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Switches to enable/disable logging targets
|
||||
// MUST BE DEFINED BEFORE gConfig FOR gLogEarly() TO WORK CORRECTLY
|
||||
bool gLogToConsole = true;
|
||||
bool gLogToSyslog = false;
|
||||
FILE *gLogToFile = NULL;
|
||||
Mutex gLogToLock;
|
||||
|
||||
|
||||
// Reference to a global config table, used all over the system.
|
||||
extern ConfigurationTable gConfig;
|
||||
|
||||
@@ -67,10 +75,6 @@ const char *levelNames[] = {
|
||||
"EMERG", "ALERT", "CRIT", "ERR", "WARNING", "NOTICE", "INFO", "DEBUG"
|
||||
};
|
||||
int numLevels = 8;
|
||||
bool gLogToConsole = true;
|
||||
bool gLogToSyslog = false;
|
||||
FILE *gLogToFile = NULL;
|
||||
Mutex gLogToLock;
|
||||
|
||||
|
||||
int levelStringToInt(const string& name)
|
||||
@@ -269,9 +273,32 @@ void gLogInit(const char* name, const char* level, int facility)
|
||||
void gLogEarly(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
||||
va_start(args, fmt);
|
||||
vsyslog(level | LOG_USER, fmt, args);
|
||||
|
||||
if (gLogToSyslog) {
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
vsyslog(level | LOG_USER, fmt, args_copy);
|
||||
va_end(args_copy);
|
||||
}
|
||||
|
||||
if (gLogToConsole) {
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
vprintf(fmt, args_copy);
|
||||
printf("\n");
|
||||
va_end(args_copy);
|
||||
}
|
||||
|
||||
if (gLogToFile) {
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
vfprintf(gLogToFile, fmt, args_copy);
|
||||
fprintf(gLogToFile, "\n");
|
||||
va_end(args_copy);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,6 @@ TransceiverState::TransceiverState()
|
||||
for (int i = 0; i < 8; i++) {
|
||||
chanType[i] = Transceiver::NONE;
|
||||
fillerModulus[i] = 26;
|
||||
chanResponse[i] = NULL;
|
||||
DFEForward[i] = NULL;
|
||||
DFEFeedback[i] = NULL;
|
||||
|
||||
for (int n = 0; n < 102; n++)
|
||||
fillerTable[n][i] = NULL;
|
||||
@@ -62,10 +59,6 @@ TransceiverState::TransceiverState()
|
||||
TransceiverState::~TransceiverState()
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
delete chanResponse[i];
|
||||
delete DFEForward[i];
|
||||
delete DFEFeedback[i];
|
||||
|
||||
for (int n = 0; n < 102; n++)
|
||||
delete fillerTable[n][i];
|
||||
}
|
||||
@@ -141,16 +134,24 @@ bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Transceiver::reset()
|
||||
{
|
||||
for (size_t i = 0; i < mTxPriorityQueues.size(); i++)
|
||||
mTxPriorityQueues[i].clear();
|
||||
}
|
||||
|
||||
Transceiver::Transceiver(int wBasePort,
|
||||
const char *wTRXAddress,
|
||||
size_t wSPS, size_t wChans,
|
||||
GSM::Time wTransmitLatency,
|
||||
RadioInterface *wRadioInterface,
|
||||
double wRssiOffset)
|
||||
double wRssiOffset,
|
||||
bool wExternalDemod)
|
||||
: mBasePort(wBasePort), mAddr(wTRXAddress),
|
||||
mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
|
||||
mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
|
||||
rssiOffset(wRssiOffset),
|
||||
mExternalDemod(wExternalDemod),
|
||||
mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
|
||||
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0), mWriteBurstToDiskMask(0)
|
||||
{
|
||||
@@ -222,7 +223,7 @@ bool Transceiver::init(int filler, size_t rtsc)
|
||||
c_srcport = mBasePort + 2 * i + 1;
|
||||
c_dstport = mBasePort + 2 * i + 101;
|
||||
d_srcport = mBasePort + 2 * i + 2;
|
||||
d_dstport = mBasePort + 2 * i + 102;
|
||||
d_dstport = mBasePort + 2 * i + (mExternalDemod?202:102);
|
||||
|
||||
mCtrlSockets[i] = new UDPSocket(c_srcport, mAddr.c_str(), c_dstport);
|
||||
mDataSockets[i] = new UDPSocket(d_srcport, mAddr.c_str(), d_dstport);
|
||||
@@ -556,11 +557,9 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect RACH synchronization sequence within a burst. No equalization
|
||||
* is used or available on the RACH channel.
|
||||
* Detect RACH synchronization sequence within a burst.
|
||||
*/
|
||||
int Transceiver::detectRACH(TransceiverState *state,
|
||||
signalVector &burst,
|
||||
int Transceiver::detectRACH(signalVector &burst,
|
||||
complex &, float &toa)
|
||||
{
|
||||
float threshold = 6.0;
|
||||
@@ -569,76 +568,16 @@ int Transceiver::detectRACH(TransceiverState *state,
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect normal burst training sequence midamble. Update equalization
|
||||
* state information and channel estimate if necessary. Equalization
|
||||
* is currently disabled.
|
||||
* Detect normal burst training sequence midamble.
|
||||
*/
|
||||
int Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
|
||||
complex &, float &toa, GSM::Time &time)
|
||||
int Transceiver::detectTSC(signalVector &burst,
|
||||
complex &, float &toa)
|
||||
{
|
||||
int success;
|
||||
int tn = time.TN();
|
||||
float chanOffset, threshold = 5.0;
|
||||
bool needDFE = false, estimateChan = false;
|
||||
double elapsed = time - state->chanEstimateTime[tn];
|
||||
signalVector *chanResp;
|
||||
|
||||
/* Check equalization update state */
|
||||
if (needDFE && ((elapsed > 50) || (!state->chanResponse[tn]))) {
|
||||
delete state->DFEForward[tn];
|
||||
delete state->DFEFeedback[tn];
|
||||
state->DFEForward[tn] = NULL;
|
||||
state->DFEFeedback[tn] = NULL;
|
||||
|
||||
estimateChan = true;
|
||||
}
|
||||
float threshold = 5.0;
|
||||
|
||||
/* Detect normal burst midambles */
|
||||
success = analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp,
|
||||
toa, mMaxExpectedDelay, estimateChan,
|
||||
&chanResp, &chanOffset);
|
||||
if (success <= 0) {
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Set equalizer if unabled */
|
||||
if (needDFE && estimateChan) {
|
||||
float noise = state->mNoiseLev;
|
||||
state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
|
||||
|
||||
state->chanResponse[tn] = chanResp;
|
||||
state->chanRespOffset[tn] = chanOffset;
|
||||
state->chanRespAmplitude[tn] = amp;
|
||||
|
||||
scaleVector(*chanResp, complex(1.0, 0.0) / amp);
|
||||
|
||||
designDFE(*chanResp, state->SNRestimate[tn],
|
||||
7, &state->DFEForward[tn], &state->DFEFeedback[tn]);
|
||||
|
||||
state->chanEstimateTime[tn] = time;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Demodulate GMSK burst using equalization if requested. Otherwise
|
||||
* demodulate by direct rotation and soft slicing.
|
||||
*/
|
||||
SoftVector *Transceiver::demodulate(TransceiverState *state,
|
||||
signalVector &burst, complex amp,
|
||||
float toa, size_t tn, bool equalize)
|
||||
{
|
||||
if (equalize) {
|
||||
scaleVector(burst, complex(1.0, 0.0) / amp);
|
||||
return equalizeBurst(burst,
|
||||
toa - state->chanRespOffset[tn],
|
||||
mSPSRx,
|
||||
*state->DFEForward[tn],
|
||||
*state->DFEFeedback[tn]);
|
||||
}
|
||||
|
||||
return demodulateBurst(burst, mSPSRx, amp, toa);
|
||||
return analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp,
|
||||
toa, mMaxExpectedDelay);
|
||||
}
|
||||
|
||||
void writeToFile(radioVector *radio_burst, size_t chan)
|
||||
@@ -655,42 +594,47 @@ void writeToFile(radioVector *radio_burst, size_t chan)
|
||||
* Pull bursts from the FIFO and handle according to the slot
|
||||
* and burst correlation type. Equalzation is currently disabled.
|
||||
*/
|
||||
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
|
||||
double &timingOffset, double &noise,
|
||||
size_t chan)
|
||||
SoftVector *Transceiver::demodSignalVector(signalVector *burst,
|
||||
CorrType type,
|
||||
double &timingOffset)
|
||||
{
|
||||
int success;
|
||||
bool equalize = false;
|
||||
complex amp;
|
||||
float toa, pow, max = -1.0, avg = 0.0;
|
||||
int max_i = -1;
|
||||
signalVector *burst;
|
||||
float toa;
|
||||
SoftVector *bits = NULL;
|
||||
TransceiverState *state = &mStates[chan];
|
||||
isRssiValid = false;
|
||||
|
||||
/* Blocking FIFO read */
|
||||
radioVector *radio_burst = mReceiveFIFO[chan]->read();
|
||||
if (!radio_burst)
|
||||
return NULL;
|
||||
/* Detect normal or RACH bursts */
|
||||
if (type == TSC)
|
||||
success = detectTSC(*burst, amp, toa);
|
||||
else
|
||||
success = detectRACH(*burst, amp, toa);
|
||||
|
||||
/* Set time and determine correlation type */
|
||||
GSM::Time time = radio_burst->getTime();
|
||||
CorrType type = expectedCorrType(time, chan);
|
||||
/* Alert an error and exit */
|
||||
if (success <= 0) {
|
||||
if (success == -SIGERR_CLIP) {
|
||||
LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
|
||||
} else if (success != SIGERR_NONE) {
|
||||
LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
|
||||
}
|
||||
|
||||
/* Debug: dump bursts to disk */
|
||||
/* bits 0-7 - chan 0 timeslots
|
||||
* bits 8-15 - chan 1 timeslots */
|
||||
if (mWriteBurstToDiskMask & ((1<<time.TN()) << (8*chan)))
|
||||
writeToFile(radio_burst, chan);
|
||||
|
||||
/* No processing if the timeslot is off.
|
||||
* Not even power level or noise calculation. */
|
||||
if (type == OFF) {
|
||||
delete radio_burst;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timingOffset = toa / mSPSRx;
|
||||
|
||||
bits = demodulateBurst(*burst, mSPSRx, amp, toa);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
signalVector *Transceiver::chooseDiversityPath(radioVector *radio_burst, double &avg)
|
||||
{
|
||||
signalVector *burst;
|
||||
int max_i = -1;
|
||||
float pow, max = -1.0;
|
||||
|
||||
avg = 0.0;
|
||||
|
||||
/* Select the diversity channel with highest energy */
|
||||
for (size_t i = 0; i < radio_burst->chans(); i++) {
|
||||
energyDetect(*radio_burst->getVector(i), 20 * mSPSRx, 0.0, &pow);
|
||||
@@ -703,7 +647,6 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i
|
||||
|
||||
if (max_i < 0) {
|
||||
LOG(ALERT) << "Received empty burst";
|
||||
delete radio_burst;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -711,62 +654,16 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i
|
||||
burst = radio_burst->getVector(max_i);
|
||||
avg = sqrt(avg / radio_burst->chans());
|
||||
|
||||
wTime = time;
|
||||
RSSI = 20.0 * log10(rxFullScale / avg);
|
||||
|
||||
/* RSSI estimation are valid */
|
||||
isRssiValid = true;
|
||||
|
||||
if (type == IDLE) {
|
||||
/* Update noise levels */
|
||||
state->mNoises.insert(avg);
|
||||
state->mNoiseLev = state->mNoises.avg();
|
||||
noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
|
||||
|
||||
delete radio_burst;
|
||||
return NULL;
|
||||
} else {
|
||||
/* Do not update noise levels */
|
||||
noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
|
||||
}
|
||||
|
||||
/* Detect normal or RACH bursts */
|
||||
if (type == TSC)
|
||||
success = detectTSC(state, *burst, amp, toa, time);
|
||||
else
|
||||
success = detectRACH(state, *burst, amp, toa);
|
||||
|
||||
/* Alert an error and exit */
|
||||
if (success <= 0) {
|
||||
if (success == -SIGERR_CLIP) {
|
||||
LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
|
||||
} else if (success != SIGERR_NONE) {
|
||||
LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
|
||||
}
|
||||
|
||||
delete radio_burst;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timingOffset = toa / mSPSRx;
|
||||
|
||||
/* Demodulate and set output info */
|
||||
if (equalize && (type != TSC))
|
||||
equalize = false;
|
||||
|
||||
bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
|
||||
|
||||
delete radio_burst;
|
||||
return bits;
|
||||
return burst;
|
||||
}
|
||||
|
||||
void Transceiver::reset()
|
||||
void TransceiverState::updateNoiseEstimates(double avg)
|
||||
{
|
||||
for (size_t i = 0; i < mTxPriorityQueues.size(); i++)
|
||||
mTxPriorityQueues[i].clear();
|
||||
/* Update noise levels */
|
||||
mNoises.insert(avg);
|
||||
mNoiseLev = mNoises.avg();
|
||||
}
|
||||
|
||||
|
||||
void Transceiver::driveControl(size_t chan)
|
||||
{
|
||||
int MAX_PACKET_LENGTH = 100;
|
||||
@@ -841,9 +738,8 @@ void Transceiver::driveControl(size_t chan)
|
||||
}
|
||||
else if (strcmp(command,"NOISELEV")==0) {
|
||||
if (mOn) {
|
||||
float lev = mStates[chan].mNoiseLev;
|
||||
sprintf(response,"RSP NOISELEV 0 %d",
|
||||
(int) round(20.0 * log10(rxFullScale / lev)));
|
||||
(int) round(dB2(rxFullScale / mStates[chan].mNoiseLev)));
|
||||
}
|
||||
else {
|
||||
sprintf(response,"RSP NOISELEV 1 0");
|
||||
@@ -980,20 +876,64 @@ void Transceiver::driveReceiveRadio()
|
||||
|
||||
void Transceiver::driveReceiveFIFO(size_t chan)
|
||||
{
|
||||
SoftVector *rxBurst = NULL;
|
||||
radioVector *radio_burst = NULL;
|
||||
signalVector *burst = NULL;
|
||||
double burst_power; // sqr(amp)
|
||||
double RSSI; // in dBFS
|
||||
double dBm; // in dBm
|
||||
double TOA; // in symbols
|
||||
int TOAint; // in 1/256 symbols
|
||||
double noise; // noise level in dBFS
|
||||
GSM::Time burstTime;
|
||||
bool isRssiValid; // are RSSI, noise and burstTime valid
|
||||
CorrType burstType;
|
||||
char burstString[3000];
|
||||
int pktLen;
|
||||
|
||||
rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan);
|
||||
/* Blocking FIFO read */
|
||||
radio_burst = mReceiveFIFO[chan]->read();
|
||||
if (!radio_burst)
|
||||
return;
|
||||
|
||||
if (rxBurst) {
|
||||
dBm = RSSI+rssiOffset;
|
||||
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
|
||||
/* Set time and determine correlation type */
|
||||
burstTime = radio_burst->getTime();
|
||||
burstType = expectedCorrType(burstTime, chan);
|
||||
|
||||
/* Debug: dump bursts to disk */
|
||||
/* bits 0-7 - chan 0 timeslots
|
||||
* bits 8-15 - chan 1 timeslots */
|
||||
if (mWriteBurstToDiskMask & ((1<<burstTime.TN()) << (8*chan)))
|
||||
writeToFile(radio_burst, chan);
|
||||
|
||||
/* No processing if the timeslot is off. */
|
||||
if (burstType == OFF) {
|
||||
delete radio_burst;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Choose a diversity channel to use */
|
||||
/* Returned value is a pointer to the radio_burst internal structure */
|
||||
burst = chooseDiversityPath(radio_burst, burst_power);
|
||||
if (!burst) {
|
||||
delete radio_burst;
|
||||
return;
|
||||
}
|
||||
|
||||
/* We use idle timeslots to calculate noise levels for informational purposes.
|
||||
* Otherwise we ignore them. */
|
||||
if (burstType == IDLE) {
|
||||
mStates[chan].updateNoiseEstimates(burst_power);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update/calculate burst info */
|
||||
noise = dB2(rxFullScale / mStates[chan].mNoiseLev);
|
||||
RSSI = dB2(rxFullScale / burst_power);
|
||||
dBm = RSSI+rssiOffset;
|
||||
|
||||
if (!mExternalDemod) {
|
||||
/* Pre-process and demodulate radio vector */
|
||||
SoftVector *rxBurst = demodSignalVector(burst, burstType, TOA);
|
||||
if (!rxBurst)
|
||||
return;
|
||||
|
||||
LOG(DEBUG) << std::fixed << std::right
|
||||
<< " time: " << burstTime
|
||||
@@ -1002,23 +942,67 @@ void Transceiver::driveReceiveFIFO(size_t chan)
|
||||
<< " TOA: " << std::setw(5) << std::setprecision(2) << TOA
|
||||
<< " bits: " << *rxBurst;
|
||||
|
||||
char burstString[gSlotLen+10];
|
||||
burstString[0] = burstTime.TN();
|
||||
for (int i = 0; i < 4; i++)
|
||||
burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
|
||||
burstString[5] = (int)dBm;
|
||||
burstString[6] = (TOAint >> 8) & 0x0ff;
|
||||
burstString[7] = TOAint & 0x0ff;
|
||||
SoftVector::iterator burstItr = rxBurst->begin();
|
||||
|
||||
for (unsigned int i = 0; i < gSlotLen; i++) {
|
||||
burstString[8+i] =(char) round((*burstItr++)*255.0);
|
||||
}
|
||||
burstString[gSlotLen+9] = '\0';
|
||||
pktLen = formatDemodPacket(burstTime, dBm, TOA, rxBurst, burstString);
|
||||
delete rxBurst;
|
||||
|
||||
mDataSockets[chan]->write(burstString,gSlotLen+10);
|
||||
} else {
|
||||
/* Send radio vector as is */
|
||||
pktLen = formatRawPacket(burstTime, dBm, TOA, burstType, mTSC, burst, burstString);
|
||||
}
|
||||
|
||||
mDataSockets[chan]->write(burstString, pktLen);
|
||||
|
||||
delete radio_burst;
|
||||
}
|
||||
|
||||
int Transceiver::formatCommonPacketHeader(GSM::Time burstTime, double dBm, double TOA,
|
||||
char *burstString)
|
||||
{
|
||||
int TOAint; // in 1/256 symbols
|
||||
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
|
||||
|
||||
burstString[0] = burstTime.TN();
|
||||
for (int i = 0; i < 4; i++)
|
||||
burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
|
||||
burstString[5] = (int)dBm;
|
||||
burstString[6] = (TOAint >> 8) & 0x0ff;
|
||||
burstString[7] = TOAint & 0x0ff;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
int Transceiver::formatDemodPacket(GSM::Time burstTime, double dBm, double TOA,
|
||||
SoftVector *rxBurst, char *burstString)
|
||||
{
|
||||
int headerSize = formatCommonPacketHeader(burstTime, dBm, TOA, burstString);
|
||||
SoftVector::iterator burstItr = rxBurst->begin();
|
||||
|
||||
for (unsigned int i = 0; i < gSlotLen; i++) {
|
||||
burstString[headerSize+i] =(char) round((*burstItr++)*255.0);
|
||||
}
|
||||
burstString[gSlotLen+headerSize+1] = '\0';
|
||||
|
||||
return gSlotLen+headerSize+2;
|
||||
}
|
||||
|
||||
int Transceiver::formatRawPacket(GSM::Time burstTime, double dBm, double TOA,
|
||||
CorrType burstType, unsigned tsc,
|
||||
signalVector *rxBurst, char *burstString)
|
||||
{
|
||||
int headerSize = formatCommonPacketHeader(burstTime, dBm, TOA, burstString);
|
||||
burstString[headerSize++] = burstType;
|
||||
burstString[headerSize++] = tsc;
|
||||
burstString[headerSize++] = 0; // alignment
|
||||
burstString[headerSize++] = 0; // alignment
|
||||
|
||||
signalVector::iterator burstItr = rxBurst->begin();
|
||||
float *signalItr = (float*)(&burstString[headerSize]);
|
||||
|
||||
for (unsigned int i = 0; i < gSlotLen; i++, burstItr++) {
|
||||
signalItr[2*i] = (*burstItr).real();
|
||||
signalItr[2*i+1] = (*burstItr).imag();
|
||||
}
|
||||
|
||||
return headerSize + 2*gSlotLen*sizeof(float);
|
||||
}
|
||||
|
||||
void Transceiver::driveTxFIFO()
|
||||
|
||||
@@ -55,29 +55,15 @@ struct TransceiverState {
|
||||
|
||||
/* Initialize a multiframe slot in the filler table */
|
||||
bool init(int filler, size_t sps, float scale, size_t rtsc);
|
||||
void updateNoiseEstimates(double avg);
|
||||
|
||||
int chanType[8];
|
||||
|
||||
/* Last timestamp of each timeslot's channel estimate */
|
||||
GSM::Time chanEstimateTime[8];
|
||||
|
||||
/* The filler table */
|
||||
signalVector *fillerTable[102][8];
|
||||
int fillerModulus[8];
|
||||
bool mRetrans;
|
||||
|
||||
/* Most recent channel estimate of all timeslots */
|
||||
signalVector *chanResponse[8];
|
||||
|
||||
/* Most recent DFE feedback filter of all timeslots */
|
||||
signalVector *DFEForward[8];
|
||||
signalVector *DFEFeedback[8];
|
||||
|
||||
/* Most recent SNR, timing, and channel amplitude estimates */
|
||||
float SNRestimate[8];
|
||||
float chanRespOffset[8];
|
||||
complex chanRespAmplitude[8];
|
||||
|
||||
/* Received noise energy levels */
|
||||
float mNoiseLev;
|
||||
noiseVector mNoises;
|
||||
@@ -101,7 +87,8 @@ public:
|
||||
size_t wSPS, size_t chans,
|
||||
GSM::Time wTransmitLatency,
|
||||
RadioInterface *wRadioInterface,
|
||||
double wRssiOffset);
|
||||
double wRssiOffset,
|
||||
bool wExternalDemod);
|
||||
|
||||
/** Destructor */
|
||||
~Transceiver();
|
||||
@@ -184,6 +171,8 @@ private:
|
||||
|
||||
double rssiOffset; ///< RSSI to dBm conversion offset
|
||||
|
||||
bool mExternalDemod; ///< Should we internal or external demod
|
||||
|
||||
/** modulate and add a burst to the transmit queue */
|
||||
void addRadioVector(size_t chan, BitVector &bits,
|
||||
int RSSI, GSM::Time &wTime);
|
||||
@@ -195,9 +184,15 @@ private:
|
||||
void pushRadioVector(GSM::Time &nowTime);
|
||||
|
||||
/** Pull and demodulate a burst from the receive FIFO */
|
||||
SoftVector *pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
|
||||
double &timingOffset, double &noise,
|
||||
size_t chan = 0);
|
||||
SoftVector *demodSignalVector(signalVector *burst,
|
||||
CorrType type,
|
||||
double &timingOffset);
|
||||
|
||||
/** choose the channel to use */
|
||||
signalVector *chooseDiversityPath(radioVector *radio_burst, double &avg);
|
||||
|
||||
/** update noise estimate */
|
||||
double updateNoiseEstimates(TransceiverState *state, double avg);
|
||||
|
||||
/** Set modulus for specific timeslot */
|
||||
void setModulus(size_t timeslot, size_t chan);
|
||||
@@ -209,19 +204,12 @@ private:
|
||||
void writeClockInterface(void);
|
||||
|
||||
/** Detect RACH bursts */
|
||||
int detectRACH(TransceiverState *state,
|
||||
signalVector &burst,
|
||||
int detectRACH(signalVector &burst,
|
||||
complex &, float &toa);
|
||||
|
||||
/** Detect normal bursts */
|
||||
int detectTSC(TransceiverState *state,
|
||||
signalVector &burst,
|
||||
complex &, float &toa, GSM::Time &time);
|
||||
|
||||
/** Demodulat burst and output soft bits */
|
||||
SoftVector *demodulate(TransceiverState *state,
|
||||
signalVector &burst, complex amp,
|
||||
float toa, size_t tn, bool equalize);
|
||||
int detectTSC(signalVector &burst,
|
||||
complex &, float &toa);
|
||||
|
||||
int mSPSTx; ///< number of samples per Tx symbol
|
||||
int mSPSRx; ///< number of samples per Rx symbol
|
||||
@@ -251,6 +239,19 @@ protected:
|
||||
/** drive demodulation of GSM bursts */
|
||||
void driveReceiveFIFO(size_t chan);
|
||||
|
||||
/** format a common header for packets with sent over the network */
|
||||
int formatCommonPacketHeader(GSM::Time burstTime, double dBm, double TOA,
|
||||
char *burstString);
|
||||
|
||||
/** format a packet of soft-bits to be sent over the network */
|
||||
int formatDemodPacket(GSM::Time burstTime, double dBm, double TOA,
|
||||
SoftVector *rxBurst, char *burstString);
|
||||
|
||||
/** format a packet of raw samples to be sent over the network */
|
||||
int formatRawPacket(GSM::Time burstTime, double dBm, double TOA,
|
||||
CorrType burstType, unsigned tsc,
|
||||
signalVector *rxBurst, char *burstString);
|
||||
|
||||
/** drive transmission of GSM bursts */
|
||||
void driveTxFIFO();
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ struct trx_config {
|
||||
double offset;
|
||||
double rssi_offset;
|
||||
bool swap_channels;
|
||||
bool external_demod;
|
||||
};
|
||||
|
||||
ConfigurationTable gConfig;
|
||||
@@ -189,6 +190,7 @@ bool trx_setup_config(struct trx_config *config)
|
||||
ost << " Tuning offset........... " << config->offset << std::endl;
|
||||
ost << " RSSI to dBm offset...... " << config->rssi_offset << std::endl;
|
||||
ost << " Swap channels........... " << config->swap_channels << std::endl;
|
||||
ost << " External demodulator.... " << config->external_demod << std::endl;
|
||||
std::cout << ost << std::endl;
|
||||
|
||||
return true;
|
||||
@@ -244,7 +246,7 @@ Transceiver *makeTransceiver(struct trx_config *config, RadioInterface *radio)
|
||||
VectorFIFO *fifo;
|
||||
|
||||
trx = new Transceiver(config->port, config->addr.c_str(), config->sps,
|
||||
config->chans, GSM::Time(3,0), radio, config->rssi_offset);
|
||||
config->chans, GSM::Time(3,0), radio, config->rssi_offset, config->external_demod);
|
||||
if (!trx->init(config->filler, config->rtsc)) {
|
||||
LOG(ALERT) << "Failed to initialize transceiver";
|
||||
delete trx;
|
||||
@@ -298,8 +300,9 @@ static void print_help()
|
||||
" -o Set baseband frequency offset (default=auto)\n"
|
||||
" -r Random burst test mode with TSC\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");
|
||||
" -S Swap channels (UmTRX only)\n"
|
||||
" -e External demodulator - stream raw samples instead of soft bits (default=internal)\n",
|
||||
"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
@@ -316,8 +319,9 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
config->offset = 0.0;
|
||||
config->rssi_offset = 0.0;
|
||||
config->swap_channels = false;
|
||||
config->external_demod = false;
|
||||
|
||||
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:S")) != -1) {
|
||||
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:Se")) != -1) {
|
||||
switch (option) {
|
||||
case 'h':
|
||||
print_help();
|
||||
@@ -363,6 +367,9 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
||||
case 'S':
|
||||
config->swap_channels = true;
|
||||
break;
|
||||
case 'e':
|
||||
config->external_demod = true;
|
||||
break;
|
||||
default:
|
||||
print_help();
|
||||
exit(0);
|
||||
|
||||
@@ -147,64 +147,8 @@ void sigProcLibDestroy()
|
||||
GSMPulse1 = NULL;
|
||||
}
|
||||
|
||||
// dB relative to 1.0.
|
||||
// if > 1.0, then return 0 dB
|
||||
float dB(float x) {
|
||||
|
||||
float arg = 1.0F;
|
||||
float dB = 0.0F;
|
||||
|
||||
if (x >= 1.0F) return 0.0F;
|
||||
if (x <= 0.0F) return -200.0F;
|
||||
|
||||
float prevArg = arg;
|
||||
float prevdB = dB;
|
||||
float stepSize = 16.0F;
|
||||
float dBstepSize = 12.0F;
|
||||
while (stepSize > 1.0F) {
|
||||
do {
|
||||
prevArg = arg;
|
||||
prevdB = dB;
|
||||
arg /= stepSize;
|
||||
dB -= dBstepSize;
|
||||
} while (arg > x);
|
||||
arg = prevArg;
|
||||
dB = prevdB;
|
||||
stepSize *= 0.5F;
|
||||
dBstepSize -= 3.0F;
|
||||
}
|
||||
return ((arg-x)*(dB-3.0F) + (x-arg*0.5F)*dB)/(arg - arg*0.5F);
|
||||
|
||||
}
|
||||
|
||||
// 10^(-dB/10), inverse of dB func.
|
||||
float dBinv(float x) {
|
||||
|
||||
float arg = 1.0F;
|
||||
float dB = 0.0F;
|
||||
|
||||
if (x >= 0.0F) return 1.0F;
|
||||
if (x <= -200.0F) return 0.0F;
|
||||
|
||||
float prevArg = arg;
|
||||
float prevdB = dB;
|
||||
float stepSize = 16.0F;
|
||||
float dBstepSize = 12.0F;
|
||||
while (stepSize > 1.0F) {
|
||||
do {
|
||||
prevArg = arg;
|
||||
prevdB = dB;
|
||||
arg /= stepSize;
|
||||
dB -= dBstepSize;
|
||||
} while (dB > x);
|
||||
arg = prevArg;
|
||||
dB = prevdB;
|
||||
stepSize *= 0.5F;
|
||||
dBstepSize -= 3.0F;
|
||||
}
|
||||
|
||||
return ((dB-x)*(arg*0.5F)+(x-(dB-3.0F))*(arg))/3.0F;
|
||||
|
||||
double dB2(double x) {
|
||||
return 20.0 * log10(x);
|
||||
}
|
||||
|
||||
float vectorNorm2(const signalVector &x)
|
||||
@@ -1478,8 +1422,7 @@ int detectRACHBurst(signalVector &rxBurst,
|
||||
* tail: Search 4 symbols + maximum expected delay
|
||||
*/
|
||||
int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
|
||||
int sps, complex &, float &toa, unsigned max_toa,
|
||||
bool chan_req, signalVector **chan, float *chan_offset)
|
||||
int sps, complex &, float &toa, unsigned max_toa)
|
||||
{
|
||||
int rc, target, head, tail;
|
||||
CorrelationSequence *sync;
|
||||
@@ -1495,14 +1438,6 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
|
||||
rc = detectGeneralBurst(rxBurst, thresh, sps, amp, toa,
|
||||
target, head, tail, sync);
|
||||
|
||||
/* Equalization not currently supported */
|
||||
if (rc > 0 && chan_req) {
|
||||
*chan = new signalVector(6 * sps);
|
||||
|
||||
if (chan_offset)
|
||||
*chan_offset = 0.0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1559,166 +1494,6 @@ SoftVector *demodulateBurst(signalVector &rxBurst, int sps,
|
||||
return bits;
|
||||
}
|
||||
|
||||
// Assumes symbol-spaced sampling!!!
|
||||
// Based upon paper by Al-Dhahir and Cioffi
|
||||
bool designDFE(signalVector &channelResponse,
|
||||
float SNRestimate,
|
||||
int Nf,
|
||||
signalVector **feedForwardFilter,
|
||||
signalVector **feedbackFilter)
|
||||
{
|
||||
|
||||
signalVector G0(Nf);
|
||||
signalVector G1(Nf);
|
||||
signalVector::iterator G0ptr = G0.begin();
|
||||
signalVector::iterator G1ptr = G1.begin();
|
||||
signalVector::iterator chanPtr = channelResponse.begin();
|
||||
|
||||
int nu = channelResponse.size()-1;
|
||||
|
||||
*G0ptr = 1.0/sqrtf(SNRestimate);
|
||||
for(int j = 0; j <= nu; j++) {
|
||||
*G1ptr = chanPtr->conj();
|
||||
G1ptr++; chanPtr++;
|
||||
}
|
||||
|
||||
signalVector *L[Nf];
|
||||
signalVector::iterator Lptr;
|
||||
float d = 1.0;
|
||||
for(int i = 0; i < Nf; i++) {
|
||||
d = G0.begin()->norm2() + G1.begin()->norm2();
|
||||
L[i] = new signalVector(Nf+nu);
|
||||
Lptr = L[i]->begin()+i;
|
||||
G0ptr = G0.begin(); G1ptr = G1.begin();
|
||||
while ((G0ptr < G0.end()) && (Lptr < L[i]->end())) {
|
||||
*Lptr = (*G0ptr*(G0.begin()->conj()) + *G1ptr*(G1.begin()->conj()) )/d;
|
||||
Lptr++;
|
||||
G0ptr++;
|
||||
G1ptr++;
|
||||
}
|
||||
complex k = (*G1.begin())/(*G0.begin());
|
||||
|
||||
if (i != Nf-1) {
|
||||
signalVector G0new = G1;
|
||||
scaleVector(G0new,k.conj());
|
||||
addVector(G0new,G0);
|
||||
|
||||
signalVector G1new = G0;
|
||||
scaleVector(G1new,k*(-1.0));
|
||||
addVector(G1new,G1);
|
||||
delayVector(&G1new, &G1new, -1.0);
|
||||
|
||||
scaleVector(G0new,1.0/sqrtf(1.0+k.norm2()));
|
||||
scaleVector(G1new,1.0/sqrtf(1.0+k.norm2()));
|
||||
G0 = G0new;
|
||||
G1 = G1new;
|
||||
}
|
||||
}
|
||||
|
||||
*feedbackFilter = new signalVector(nu);
|
||||
L[Nf-1]->segmentCopyTo(**feedbackFilter,Nf,nu);
|
||||
scaleVector(**feedbackFilter,(complex) -1.0);
|
||||
conjugateVector(**feedbackFilter);
|
||||
|
||||
signalVector v(Nf);
|
||||
signalVector::iterator vStart = v.begin();
|
||||
signalVector::iterator vPtr;
|
||||
*(vStart+Nf-1) = (complex) 1.0;
|
||||
for(int k = Nf-2; k >= 0; k--) {
|
||||
Lptr = L[k]->begin()+k+1;
|
||||
vPtr = vStart + k+1;
|
||||
complex v_k = 0.0;
|
||||
for (int j = k+1; j < Nf; j++) {
|
||||
v_k -= (*vPtr)*(*Lptr);
|
||||
vPtr++; Lptr++;
|
||||
}
|
||||
*(vStart + k) = v_k;
|
||||
}
|
||||
|
||||
*feedForwardFilter = new signalVector(Nf);
|
||||
signalVector::iterator w = (*feedForwardFilter)->end();
|
||||
for (int i = 0; i < Nf; i++) {
|
||||
delete L[i];
|
||||
complex w_i = 0.0;
|
||||
int endPt = ( nu < (Nf-1-i) ) ? nu : (Nf-1-i);
|
||||
vPtr = vStart+i;
|
||||
chanPtr = channelResponse.begin();
|
||||
for (int k = 0; k < endPt+1; k++) {
|
||||
w_i += (*vPtr)*(chanPtr->conj());
|
||||
vPtr++; chanPtr++;
|
||||
}
|
||||
*--w = w_i/d;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Assumes symbol-rate sampling!!!!
|
||||
SoftVector *equalizeBurst(signalVector &rxBurst,
|
||||
float TOA,
|
||||
int sps,
|
||||
signalVector &w, // feedforward filter
|
||||
signalVector &b) // feedback filter
|
||||
{
|
||||
signalVector *postForwardFull;
|
||||
|
||||
if (!delayVector(&rxBurst, &rxBurst, -TOA))
|
||||
return NULL;
|
||||
|
||||
postForwardFull = convolve(&rxBurst, &w, NULL,
|
||||
CUSTOM, 0, rxBurst.size() + w.size() - 1);
|
||||
if (!postForwardFull)
|
||||
return NULL;
|
||||
|
||||
signalVector* postForward = new signalVector(rxBurst.size());
|
||||
postForwardFull->segmentCopyTo(*postForward,w.size()-1,rxBurst.size());
|
||||
delete postForwardFull;
|
||||
|
||||
signalVector::iterator dPtr = postForward->begin();
|
||||
signalVector::iterator dBackPtr;
|
||||
signalVector::iterator rotPtr = GMSKRotationN->begin();
|
||||
signalVector::iterator revRotPtr = GMSKReverseRotationN->begin();
|
||||
|
||||
signalVector *DFEoutput = new signalVector(postForward->size());
|
||||
signalVector::iterator DFEItr = DFEoutput->begin();
|
||||
|
||||
// NOTE: can insert the midamble and/or use midamble to estimate BER
|
||||
for (; dPtr < postForward->end(); dPtr++) {
|
||||
dBackPtr = dPtr-1;
|
||||
signalVector::iterator bPtr = b.begin();
|
||||
while ( (bPtr < b.end()) && (dBackPtr >= postForward->begin()) ) {
|
||||
*dPtr = *dPtr + (*bPtr)*(*dBackPtr);
|
||||
bPtr++;
|
||||
dBackPtr--;
|
||||
}
|
||||
*dPtr = *dPtr * (*revRotPtr);
|
||||
*DFEItr = *dPtr;
|
||||
// make decision on symbol
|
||||
*dPtr = (dPtr->real() > 0.0) ? 1.0 : -1.0;
|
||||
//*DFEItr = *dPtr;
|
||||
*dPtr = *dPtr * (*rotPtr);
|
||||
DFEItr++;
|
||||
rotPtr++;
|
||||
revRotPtr++;
|
||||
}
|
||||
|
||||
vectorSlicer(DFEoutput);
|
||||
|
||||
SoftVector *burstBits = new SoftVector(postForward->size());
|
||||
SoftVector::iterator burstItr = burstBits->begin();
|
||||
DFEItr = DFEoutput->begin();
|
||||
for (; DFEItr < DFEoutput->end(); DFEItr++)
|
||||
*burstItr++ = DFEItr->real();
|
||||
|
||||
delete postForward;
|
||||
|
||||
delete DFEoutput;
|
||||
|
||||
return burstBits;
|
||||
}
|
||||
|
||||
bool sigProcLibSetup(int sps)
|
||||
{
|
||||
if ((sps != 1) && (sps != 4))
|
||||
|
||||
@@ -36,8 +36,8 @@ enum signalError {
|
||||
SIGERR_INTERNAL,
|
||||
};
|
||||
|
||||
/** Convert a linear number to a dB value */
|
||||
float dB(float x);
|
||||
/** Convert a power value to a dB value */
|
||||
double dB2(double x);
|
||||
|
||||
/** Convert a dB value into a linear value */
|
||||
float dBinv(float x);
|
||||
@@ -204,9 +204,6 @@ int detectRACHBurst(signalVector &rxBurst,
|
||||
@param amplitude The estimated amplitude of received TSC burst.
|
||||
@param TOA The estimate time-of-arrival of received TSC burst.
|
||||
@param maxTOA The maximum expected time-of-arrival
|
||||
@param requestChannel Set to true if channel estimation is desired.
|
||||
@param channelResponse The estimated channel.
|
||||
@param channelResponseOffset The time offset b/w the first sample of the channel response and the reported TOA.
|
||||
@return positive if threshold value is reached, negative on error, zero otherwise
|
||||
*/
|
||||
int analyzeTrafficBurst(signalVector &rxBurst,
|
||||
@@ -215,10 +212,7 @@ int analyzeTrafficBurst(signalVector &rxBurst,
|
||||
int sps,
|
||||
complex &litude,
|
||||
float &TOA,
|
||||
unsigned maxTOA,
|
||||
bool requestChannel = false,
|
||||
signalVector** channelResponse = NULL,
|
||||
float *channelResponseOffset = NULL);
|
||||
unsigned maxTOA);
|
||||
|
||||
/**
|
||||
Decimate a vector.
|
||||
@@ -240,34 +234,4 @@ signalVector *decimateVector(signalVector &wVector, size_t factor);
|
||||
SoftVector *demodulateBurst(signalVector &rxBurst, int sps,
|
||||
complex channel, float TOA);
|
||||
|
||||
/**
|
||||
Design the necessary filters for a decision-feedback equalizer.
|
||||
@param channelResponse The multipath channel that we're mitigating.
|
||||
@param SNRestimate The signal-to-noise estimate of the channel, a linear value
|
||||
@param Nf The number of taps in the feedforward filter.
|
||||
@param feedForwardFilter The designed feed forward filter.
|
||||
@param feedbackFilter The designed feedback filter.
|
||||
@return True if DFE can be designed.
|
||||
*/
|
||||
bool designDFE(signalVector &channelResponse,
|
||||
float SNRestimate,
|
||||
int Nf,
|
||||
signalVector **feedForwardFilter,
|
||||
signalVector **feedbackFilter);
|
||||
|
||||
/**
|
||||
Equalize/demodulate a received burst via a decision-feedback equalizer.
|
||||
@param rxBurst The received burst to be demodulated.
|
||||
@param TOA The time-of-arrival of the received burst.
|
||||
@param sps The number of samples per GSM symbol.
|
||||
@param w The feed forward filter of the DFE.
|
||||
@param b The feedback filter of the DFE.
|
||||
@return The demodulated bit sequence.
|
||||
*/
|
||||
SoftVector *equalizeBurst(signalVector &rxBurst,
|
||||
float TOA,
|
||||
int sps,
|
||||
signalVector &w,
|
||||
signalVector &b);
|
||||
|
||||
#endif /* SIGPROCLIB_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
if !ARCH_ARM
|
||||
AM_CFLAGS = -Wall -std=gnu99 -march=native -I../common
|
||||
AM_CFLAGS = -Wall -std=gnu99 -I../common
|
||||
|
||||
noinst_LTLIBRARIES = libarch.la
|
||||
|
||||
|
||||
19
debian/changelog
vendored
Normal file
19
debian/changelog
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
osmo-trx (0.1.9~1) trusty; urgency=medium
|
||||
|
||||
* minor debian changes
|
||||
* correct atom cross-compilation
|
||||
* corrected build-time and run-time dependencies
|
||||
|
||||
-- Kirill Zakharenko <earwin@gmail.com> Thu, 23 Jul 2015 00:01:07 +0000
|
||||
|
||||
osmo-trx (0.1.9) trusty; urgency=medium
|
||||
|
||||
* Ask Ivan, really
|
||||
|
||||
-- Kirill Zakharenko <earwin@gmail.com> Thu, 16 Jul 2015 12:13:46 +0000
|
||||
|
||||
osmo-trx (0.1.8) precise; urgency=low
|
||||
|
||||
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP
|
||||
|
||||
-- Ivan Klyuchnikov <Ivan.Kluchnikov@fairwaves.ru> Sun, 9 Mar 2014 14:10:10 +0400
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
9
|
||||
24
debian/control
vendored
Normal file
24
debian/control
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Source: osmo-trx
|
||||
Maintainer: Ivan Klyuchnikov <ivan.kluchnikov@fairwaves.ru>
|
||||
Section: net
|
||||
Priority: optional
|
||||
Standards-Version: 3.9.3
|
||||
Build-Depends: debhelper (>= 9), autotools-dev, libdbd-sqlite3, pkg-config, dh-autoreconf, libuhd-dev, libusb-1.0-0-dev, libboost-all-dev, hardening-wrapper
|
||||
Homepage: http://openbsc.osmocom.org/trac/wiki/OsmoTRX
|
||||
Vcs-Git: git://git.osmocom.org/osmo-trx
|
||||
Vcs-Browser: http://cgit.osmocom.org/osmo-trx
|
||||
|
||||
Package: osmo-trx
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
|
||||
Description: OsmoTRX is a software-defined radio transceiver that implements the Layer 1 physical layer of a BTS
|
||||
|
||||
Package: osmo-trx-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmo-trx (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the osmo-trx
|
||||
Make debugging possible
|
||||
|
||||
|
||||
25
debian/copyright
vendored
Normal file
25
debian/copyright
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
The Debian packaging is:
|
||||
|
||||
Copyright (C) 2014 Max <max.suraev@fairwaves.ru>
|
||||
|
||||
It was downloaded from:
|
||||
|
||||
git://git.osmocom.org/osmo-trx
|
||||
|
||||
Upstream Authors:
|
||||
|
||||
Thomas Tsou <tom@tsou.cc>
|
||||
David A. Burgess <dburgess@kestrelsp.com>
|
||||
Harvind S. Samra <hssamra@kestrelsp.com>
|
||||
Raffi Sevlian <raffisev@gmail.com>
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 2012-2013 Thomas Tsou <tom@tsou.cc>
|
||||
Copyright (C) 2011 Range Networks, Inc.
|
||||
Copyright (C) 2008-2011 Free Software Foundation, Inc.
|
||||
|
||||
License:
|
||||
|
||||
GNU Affero General Public License, Version 3
|
||||
|
||||
1
debian/osmo-trx.install
vendored
Normal file
1
debian/osmo-trx.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/usr/bin/osmo-trx
|
||||
15
debian/rules
vendored
Executable file
15
debian/rules
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
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
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip --dbg-package=osmo-trx-dbg
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
||||
Reference in New Issue
Block a user