From ff9b59c223f975f0322d2dd00d8e4567827402ab Mon Sep 17 00:00:00 2001 From: Alexander Chemeris Date: Mon, 8 Jun 2015 23:48:26 -0400 Subject: 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. --- Transceiver52M/Transceiver.cpp | 87 ++++++++++++++++++++++++++++++------------ Transceiver52M/Transceiver.h | 1 + 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index f572987..174a305 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -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 - - 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 mSendEmptyBursts, then send burst data even if it is not demodulated + if ((rxBurst || mSendEmptyBursts) && isRssiValid) { + RSSIdBm = RSSI+rssiOffset; + noisedBm = noise+rssiOffset; + + 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); } } diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h index 45d3980..bf4e88d 100644 --- a/Transceiver52M/Transceiver.h +++ b/Transceiver52M/Transceiver.h @@ -163,6 +163,7 @@ private: std::vector mDataSockets; ///< socket for writing to/reading from GSM core std::vector 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 mTxPriorityQueues; ///< priority queue of transmit bursts received from GSM core std::vector mReceiveFIFO; ///< radioInterface FIFO of receive bursts -- cgit v1.2.3