diff options
Diffstat (limited to 'src/lib/decoder/openbtsstuff/GSML1FEC.cpp')
-rw-r--r-- | src/lib/decoder/openbtsstuff/GSML1FEC.cpp | 256 |
1 files changed, 0 insertions, 256 deletions
diff --git a/src/lib/decoder/openbtsstuff/GSML1FEC.cpp b/src/lib/decoder/openbtsstuff/GSML1FEC.cpp deleted file mode 100644 index 1c99a0f..0000000 --- a/src/lib/decoder/openbtsstuff/GSML1FEC.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* -* Copyright 2008 Free Software Foundation, Inc. -* -* This software is distributed under the terms of the GNU Public License. -* See the COPYING file in the main directory for details. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -*/ - - -#define NDEBUG - - -#include "GSML1FEC.h" -#include "GSMCommon.h" -#include "RxBurst.h" -//#include "GSMSAPMux.h" -//#include "GSMConfig.h" -#include "GSMTDMA.h" -#include "GSM610Tables.h" -#include "Assert.h" - - -using namespace std; -using namespace GSM; - -/* - Compilation flags: - NOCONTROL Compile without referencing control layer functions. -*/ - - -/* - - Notes on reading the GSM specifications. - - Every FEC section in GSM 05.03 uses standard names for the bits at - different stages of the encoding/decoding process. - - This is all described formally in GSM 05.03 2.2. - - "d" -- data bits. The actual payloads from L2 and the vocoders. - "p" -- parity bits. These are calculated from d. - "u" -- uncoded bits. A concatenation of d, p and inner tail bits. - "c" -- coded bits. These are the convolutionally encoded from u. - "i" -- interleaved bits. These are the output of the interleaver. - "e" -- "encrypted" bits. These are the channel bits in the radio bursts. - - The "e" bits are call "encrypted" even when encryption is not used. - - The encoding process is: - - L2 -> d -> -> calc p -> u -> c -> i -> e -> radio bursts - - The decoding process is: - - radio bursts -> e -> i -> c -> u -> check p -> d -> L2 - - Bit ordering in d is LSB-first in each octet. - Bit ordering everywhere else in the OpenBTS code is MSB-first - in every field to give contiguous fields across byte boundaries. - We use the BitVector::LSB8MSB() method to translate. - -*/ - -TCHFACCHL1Decoder::TCHFACCHL1Decoder(const TDMAMapping& wMapping) - : mTCHU(189), mTCHD(260), mC(456), - mClass1_c(mC.head(378)), mClass1A_d(mTCHD.head(50)), mClass2_c(mC.segment(378, 78)), - mTCHParity(0x0b, 3, 50), mMapping(wMapping) -{ - for (int i = 0; i < 8; i++) { - mI[i] = SoftVector(114); - } -} - - -void TCHFACCHL1Decoder::writeLowSide(const RxBurst& inBurst) -{ - OBJDCOUT("TCHFACCHL1Decoder::writeLowSide " << inBurst); - // If the channel is closed, ignore the burst. -// if (!active()) { -// OBJDCOUT("TCHFACCHL1Decoder::writeLowSide not active, ignoring input"); -// return; -// } - processBurst(inBurst); -} - -bool TCHFACCHL1Decoder::processBurst( const RxBurst& inBurst) -{ - // Accept the burst into the deinterleaving buffer. - // Return true if we are ready to interleave. - - // TODO -- One quick test of burst validity is to look at the tail bits. - // We could do that as a double-check against putting garbage into - // the interleaver or accepting bad parameters. - - // Get the physical parameters of the burst. - // RSSI is dB wrt full scale. -// mRSSI = inBurst.RSSI(); - // Timing error is a float in symbol intervals. -// mTimingError = inBurst.timingError(); - // This flag is used as a half-ass semaphore. - // It is cleared when the new value is read. -// mPhyNew = true; - - // The reverse index runs 0..3 as the bursts arrive. - // It is the "B" index of GSM 05.03 3.1.3 and 3.1.4. - int B = mMapping.reverseMapping(inBurst.time().FN()) % 8; - // A negative value means that the demux is misconfigured. - assert(B >= 0); - OBJDCOUT("TCHFACCHL1Decoder::processBurst B=" << B << " " << inBurst); - - // Pull the data fields (e-bits) out of the burst and put them into i[B][]. - // GSM 05.03 3.1.4 - inBurst.data1().copyToSegment(mI[B], 0); - inBurst.data2().copyToSegment(mI[B], 57); - - // Every 4th frame is the start of a new block. - // So if this isn't a "4th" frame, return now. - if (B % 4 != 3) return false; - - // Deinterleave according to the diagonal "phase" of B. - // See GSM 05.03 3.1.3. - // Deinterleaves i[] to c[] - if (B == 3) deinterleave(4); - else deinterleave(0); - - // See if this was the end of a stolen frame, GSM 05.03 4.2.5. - bool stolen = inBurst.Hl(); - OBJDCOUT("TCHFACCHL!Decoder::processBurst Hl=" << inBurst.Hl() << " Hu=" << inBurst.Hu()); - /* if (stolen) { - if (decode()) { - OBJDCOUT("TCHFACCHL1Decoder::processBurst good FACCH frame"); - countGoodFrame(); - handleGoodFrame(); - } else { - OBJDCOUT("TCHFACCHL1Decoder::processBurst bad FACCH frame"); - countBadFrame(); - } - }*/ - - // Always feed the traffic channel, even on a stolen frame. - // decodeTCH will handle the GSM 06.11 bad frmae processing. - bool traffic = decodeTCH(stolen); -// if (traffic) { - OBJDCOUT("TCHFACCHL1Decoder::processBurst good TCH frame"); -// countGoodFrame(); - // Don't let the channel timeout. - // mLock.lock(); - // mT3109.set(); - // mLock.unlock(); -// } -// else countBadFrame(); - - return traffic; -} - -void TCHFACCHL1Decoder::deinterleave(int blockOffset ) -{ - OBJDCOUT("TCHFACCHL1Decoder::deinterleave blockOffset=" << blockOffset); - for (int k = 0; k < 456; k++) { - int B = ( k + blockOffset ) % 8; - int j = 2 * ((49 * k) % 57) + ((k % 8) / 4); - mC[k] = mI[B][j]; - mI[B][j] = 0.5F; - //OBJDCOUT("deinterleave k="<<k<<" B="<<B<<" j="<<j); - } -} - -bool TCHFACCHL1Decoder::decodeTCH(bool stolen) -{ - // GSM 05.02 3.1.2, but backwards - - // If the frame wasn't stolen, we'll update this with parity later. - bool good = !stolen; - - // Good or bad, we will be sending *something* to the speech channel. - // Allocate it in this scope. - unsigned char * newFrame = new unsigned char[33]; - - if (!stolen) { - - // 3.1.2.2 - // decode from c[] to u[] - mClass1_c.decode(mVCoder, mTCHU); - //mC.head(378).decode(mVCoder,mTCHU); - - // 3.1.2.2 - // copy class 2 bits c[] to d[] - mClass2_c.sliced().copyToSegment(mTCHD, 182); - //mC.segment(378,78).sliced().copyToSegment(mTCHD,182); - - // 3.1.2.1 - // copy class 1 bits u[] to d[] - for (unsigned k = 0; k <= 90; k++) { - mTCHD[2*k] = mTCHU[k]; - mTCHD[2*k+1] = mTCHU[184-k]; - } - - // 3.1.2.1 - // check parity of class 1A - unsigned sentParity = (~mTCHU.peekField(91, 3)) & 0x07; - //unsigned calcParity = mTCHD.head(50).parity(mTCHParity) & 0x07; - unsigned calcParity = mClass1A_d.parity(mTCHParity) & 0x07; - - // 3.1.2.2 - // Check the tail bits, too. - unsigned tail = mTCHU.peekField(185, 4); - - OBJDCOUT("TCHFACCHL1Decoder::decodeTCH c[]=" << mC); - //OBJDCOUT("TCHFACCHL1Decoder::decodeTCH u[]=" << mTCHU); - OBJDCOUT("TCHFACCHL1Decoder::decodeTCH d[]=" << mTCHD); - OBJDCOUT("TCHFACCHL1Decoder::decodeTCH sentParity=" << sentParity - << " calcParity=" << calcParity << " tail=" << tail); - good = (sentParity == calcParity) && (tail == 0); - if (good) { - // Undo Um's importance-sorted bit ordering. - // See GSM 05.03 3.1 and Tablee 2. - BitVector payload = mVFrame.payload(); - mTCHD.unmap(g610BitOrder, 260, payload); - mVFrame.pack(newFrame); - // Save a copy for bad frame processing. - memcpy(mPrevGoodFrame, newFrame, 33); - return true; - } - } - - if (!good) { - // TODO -- Bad frame processing, GSM 06.11. - // For now, just repeat the last good frame. - // TODO -- Need to apply attenuation and randomization of grid positions. - memcpy(newFrame, mPrevGoodFrame, 33); - //d_gsm_file.write((char *)newFrame, 33); - } - - - // Good or bad, we must feed the speech channel. -// mSpeechQ.write(newFrame); - - - return false; -} - -// vim: ts=4 sw=4 |