/* -*- c++ -*- */ /* * Copyright 2019 Jay Arrowfield. * * This 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, or (at your option) * any later version. * * This software 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 software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "pocsag_decoder_impl.h" #define WITH_DEBUG_MESSAGES 0 namespace gr { namespace jay { pocsag_decoder::sptr pocsag_decoder::make() { return gnuradio::get_initial_sptr (new pocsag_decoder_impl()); } const char* pocsag_decoder_impl::stateNames[NUM_STATES] = {"PreambleSlow", "SyncSlow", "DataSlow", "PreambleFast", "SyncFast", "DataFast"}; /* * The private constructor */ pocsag_decoder_impl::pocsag_decoder_impl() : gr::block("pocsag_decoder", gr::io_signature::make(1, 1, sizeof(uint8_t)), gr::io_signature::make(1, 1, sizeof(uint8_t))) , m_state(PreambleSlow) , m_stateNext(PreambleSlow) , m_word(0) , m_wordCount(0) , m_wordSize(1) , m_dataCount(0) , bufferWi(0) { } /* * Our virtual destructor. */ pocsag_decoder_impl::~pocsag_decoder_impl() { } void pocsag_decoder_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { ninput_items_required[0] = 8*noutput_items; } int pocsag_decoder_impl::general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { uint8_t zero = 0x01; const uint8_t fastSyncWord[4] = {0x7C, 0xD2, 0x15, 0xD8}; const uint8_t *in = (const uint8_t *) input_items[0]; uint8_t *out = (uint8_t *) output_items[0]; // Do <+signal processing+> size_t i = 0; size_t j = 0; for (i=0; i < ninput_items[0]; i++) { if (in[i] == 0xFF) { if (m_state != PreambleSlow) { m_state = PreambleSlow; m_wordCount = 0; m_dataCount = 0; #if WITH_DEBUG_MESSAGES fprintf(stderr, "Reset\n"); #endif } continue; } if (in[i] == zero) { m_word = (m_word << 1) | 0; } else { m_word = (m_word << 1) | 1; } if (m_wordCount != 0) { m_wordCount--; continue; } m_stateNext = m_state; switch (m_state) { case PreambleSlow: #if 0 if ((m_word & 0xFF) == 0xCC) { m_wordSize = 8; m_dataCount++; if (m_dataCount == 8) { m_wordSize = 1; m_stateNext = SyncSlow; } } else #endif if ((m_word & 0xFF) == 0xAA) { m_wordSize = 8; m_dataCount++; if (m_dataCount == 4) { m_wordSize = 1; m_dataCount = 0; m_stateNext = SyncFast; } } else { m_wordSize = 1; m_dataCount = 0; } break; case SyncSlow: if ((m_word & 0xFF) == 0x3F) { m_wordSize = 8; m_dataCount = 1; out[j++] = m_word; m_stateNext = DataSlow; } break; case DataSlow: m_dataCount++; out[j++] = m_word; if (m_dataCount == 0xA0) { m_wordSize = 1; m_stateNext = PreambleFast; } break; case PreambleFast: if ((m_word & 0xFF) == 0xAA) { m_wordSize = 8; m_dataCount++; if (m_dataCount == 8) { m_wordSize = 1; m_dataCount = 0; m_stateNext = SyncFast; } } else { m_dataCount = 0; } break; case SyncFast: if ((m_word & 0xFF) == fastSyncWord[m_dataCount]) { out[j++] = m_word; m_wordSize = 8; m_dataCount++; if (m_dataCount == 4) { m_stateNext = DataFast; } } break; case DataFast: m_wordSize = 8; out[j++] = m_word; break; } if (m_state != m_stateNext) { #if WITH_DEBUG_MESSAGES fprintf(stderr, "State changed: %s => %s\n", stateNames[m_state], stateNames[m_stateNext]); #endif } m_wordCount = m_wordSize - 1; m_state = m_stateNext; } // Tell runtime system how many input items we consumed on // each input stream. consume_each (i); memcpy(&buffer[bufferWi], out, j); bufferWi += j; if (bufferWi >= 4) { size_t numProcessed = dec.process(buffer, bufferWi); bufferWi -= numProcessed; memcpy(buffer, &buffer[numProcessed], bufferWi); } // Tell runtime system how many output items we produced. return j; } } /* namespace jay */ } /* namespace gr */