Compare commits

...

1 Commits

Author SHA1 Message Date
Alexander Chemeris
ff9b59c223 Transceiver: Add an option to send RSSI to the GSM core even if the burst is not demodulated.
The feature is enabled when the GSM core sends "SENDEMPTY 1" command.
2015-06-10 23:14:11 -04:00
2 changed files with 62 additions and 24 deletions

View File

@@ -148,6 +148,7 @@ Transceiver::Transceiver(int wBasePort,
double wRssiOffset)
: mBasePort(wBasePort), mAddr(wTRXAddress),
mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
mSendEmptyBursts(false),
mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
rssiOffset(wRssiOffset),
mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
@@ -858,6 +859,16 @@ void Transceiver::driveControl(size_t chan)
sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode);
}
else if (strcmp(command,"SENDEMPTY")==0) {
int sendEmptyBursts;
sscanf(buffer,"%3s %s %d",cmdcheck,command,&sendEmptyBursts);
if (sendEmptyBursts == 0 || sendEmptyBursts == 1) {
mSendEmptyBursts = sendEmptyBursts;
sprintf(response,"RSP SENDEMPTY 0 %d",sendEmptyBursts);
} else {
sprintf(response,"RSP SENDEMPTY 1 %d",sendEmptyBursts);
}
}
else {
LOG(WARNING) << "bogus command " << command << " on control interface.";
sprintf(response,"RSP ERR 1");
@@ -914,43 +925,69 @@ void Transceiver::driveReceiveRadio()
void Transceiver::driveReceiveFIFO(size_t chan)
{
SoftVector *rxBurst = NULL;
double RSSI; // in dBFS
double dBm; // in dBm
double TOA; // in symbols
int TOAint; // in 1/256 symbols
double noise; // noise level in dBFS
double RSSI; // RSSI in dBFS
double RSSIdBm; // RSSI in dBm
double TOA; // in symbols
double noise; // noise level in dBFS
double noisedBm; // noise level in dBm
GSM::Time burstTime;
bool isRssiValid; // are RSSI, noise and burstTime valid
char burstString[gSlotLen+10];
rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan);
if (rxBurst) {
dBm = RSSI+rssiOffset;
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
// If mSendEmptyBursts, then send burst data even if it is not demodulated
if ((rxBurst || mSendEmptyBursts) && isRssiValid) {
RSSIdBm = RSSI+rssiOffset;
noisedBm = noise+rssiOffset;
LOG(DEBUG) << std::fixed << std::right
<< " time: " << burstTime
<< " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -dBm << "dBm"
<< " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -(noise+rssiOffset) << "dBm"
<< " TOA: " << std::setw(5) << std::setprecision(2) << TOA
<< " bits: " << *rxBurst;
if (rxBurst) {
LOG(DEBUG) << std::fixed << std::right
<< " time: " << burstTime
<< " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -RSSIdBm << "dBm"
<< " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -noisedBm << "dBm"
<< " TOA: " << std::setw(5) << std::setprecision(2) << TOA
<< " bits: " << *rxBurst;
} else {
LOG(DEBUG) << std::fixed << std::right
<< " time: " << burstTime
<< " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -RSSIdBm << "dBm"
<< " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -noisedBm << "dBm"
<< " no burst decoded";
}
char burstString[gSlotLen+10];
// Burst time
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);
// Burst RSSI
burstString[5] = (int)RSSIdBm;
// Time Of Arrival and actual bits
if (rxBurst) {
// Convert TOA to 1/256 symbol parts, round to closest integer
int TOAint = (int) (TOA * 256.0 + 0.5);
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);
}
delete rxBurst;
// Unused, but we check for the packet length in osmo-bts,
// so leave it as is for now
burstString[gSlotLen+8] = 0;
burstString[gSlotLen+9] = 0;
mDataSockets[chan]->write(burstString,gSlotLen+10);
} else {
// Only header
mDataSockets[chan]->write(burstString,6);
}
burstString[gSlotLen+9] = '\0';
delete rxBurst;
mDataSockets[chan]->write(burstString,gSlotLen+10);
}
}

View File

@@ -163,6 +163,7 @@ private:
std::vector<UDPSocket *> mDataSockets; ///< socket for writing to/reading from GSM core
std::vector<UDPSocket *> mCtrlSockets; ///< socket for writing/reading control commands from GSM core
UDPSocket mClockSocket; ///< socket for writing clock updates to GSM core
bool mSendEmptyBursts; ///< send RSSI to the GSM core even if burst has not been demodulated
std::vector<VectorQueue> mTxPriorityQueues; ///< priority queue of transmit bursts received from GSM core
std::vector<VectorFIFO *> mReceiveFIFO; ///< radioInterface FIFO of receive bursts