// This file is part of LeanSDR Copyright (C) 2016-2018 . // See the toplevel README for more information. // // 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 . #ifndef LEANSDR_IESS_H #define LEANSDR_IESS_H #include "leansdr/framework.h" namespace leansdr { // SELF-SYNCHRONIZING DESCRAMBLER // Per ETSI TR 192 figure 8 (except Q20/ not connected to CLOCK). // This implementation operates on packed bits, MSB first. struct etr192_descrambler : runnable { etr192_descrambler( scheduler *sch, pipebuf &_in, // Packed scrambled bits pipebuf &_out // Packed bits ) : runnable(sch, "etr192_dec"), in(_in), out(_out), shiftreg(0), counter(0) { } void run() { int count = min(in.readable(), out.writable()); for (u8 *pin = in.rd(), *pend = pin + count, *pout = out.wr(); pin < pend; ++pin, ++pout) { u8 byte_in = *pin, byte_out = 0; for (int b = 8; b--; byte_in <<= 1) { // Levels before clock transition int bit_in = (byte_in & 128) ? 1 : 0; int reset_counter = (shiftreg ^ (shiftreg >> 8)) & 1; int counter_overflow = (counter == 31) ? 1 : 0; int taps = (shiftreg >> 2) ^ (shiftreg >> 19); int bit_out = (taps ^ counter_overflow ^ bit_in ^ 1) & 1; // Execute clock transition #if 1 // Descramble shiftreg = (shiftreg << 1) | bit_in; #else // Scramble shiftreg = (shiftreg << 1) | bit_out; #endif counter = reset_counter ? 0 : (counter + 1) & 31; byte_out = (byte_out << 1) | bit_out; } *pout = byte_out; } in.read(count); out.written(count); } private: pipereader in; pipewriter out; u32 shiftreg; // 20 bits u8 counter; // 5 bits }; // etr192_descrambler } // namespace leansdr #endif // LEANSDR_IESS_H