From 08730769dc60c2665fc948f57e7dd296251bdb78 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sun, 12 Jun 2011 00:59:41 -0700 Subject: [PATCH] pull the framer out, remove the brute forcer --- src/lib/Makefile.am | 2 - src/lib/air.i | 11 ---- src/lib/air_modes_framer.cc | 124 ------------------------------------ src/lib/air_modes_framer.h | 56 ---------------- src/lib/air_modes_slicer.cc | 2 +- src/lib/modes_parity.cc | 81 ----------------------- 6 files changed, 1 insertion(+), 275 deletions(-) delete mode 100644 src/lib/air_modes_framer.cc delete mode 100644 src/lib/air_modes_framer.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index c1b40b9..9eaef77 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -24,7 +24,6 @@ include $(top_srcdir)/Makefile.common # C/C++ headers get installed in ${prefix}/include/gnuradio grinclude_HEADERS = \ air_modes_preamble.h \ - air_modes_framer.h \ air_modes_slicer.h \ air_modes_types.h \ modes_parity.h @@ -49,7 +48,6 @@ air_pythondir_category = \ # additional sources for the SWIG-generated library air_la_swig_sources = \ air_modes_preamble.cc \ - air_modes_framer.cc \ air_modes_slicer.cc \ modes_parity.cc diff --git a/src/lib/air.i b/src/lib/air.i index f094c64..05ca7b8 100644 --- a/src/lib/air.i +++ b/src/lib/air.i @@ -4,7 +4,6 @@ %{ #include "air_modes_preamble.h" -#include "air_modes_framer.h" #include "air_modes_slicer.h" #include %} @@ -28,16 +27,6 @@ private: air_modes_preamble (int channel_rate, float threshold_db); }; -GR_SWIG_BLOCK_MAGIC(air,modes_framer); - -air_modes_framer_sptr air_make_modes_framer (int channel_rate); - -class air_modes_framer : public gr_sync_block -{ -private: - air_modes_framer (int channel_rate); -}; - GR_SWIG_BLOCK_MAGIC(air,modes_slicer); air_modes_slicer_sptr air_make_modes_slicer (int channel_rate, gr_msg_queue_sptr queue); diff --git a/src/lib/air_modes_framer.cc b/src/lib/air_modes_framer.cc deleted file mode 100644 index 29da25a..0000000 --- a/src/lib/air_modes_framer.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* -# Copyright 2010 Nick Foster -# -# This file is part of gr-air-modes -# -# gr-air-modes 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. -# -# gr-air-modes 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 gr-air-modes; 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 -#include -#include -#include -#include - -air_modes_framer_sptr air_make_modes_framer(int channel_rate) -{ - return air_modes_framer_sptr (new air_modes_framer(channel_rate)); -} - -air_modes_framer::air_modes_framer(int channel_rate) : - gr_sync_block ("modes_framer", - gr_make_io_signature (1, 1, sizeof(float)), //stream 0 is received data - gr_make_io_signature (1, 1, sizeof(float))) //raw samples passed back out -{ - //initialize private data here - d_chip_rate = 2000000; //2Mchips per second - d_samples_per_chip = channel_rate / d_chip_rate; //must be integer number of samples per chip to work - d_samples_per_symbol = d_samples_per_chip * 2; - d_check_width = 120 * d_samples_per_symbol; //gotta be able to look at two long frame lengths at a time - //in the event that FRUIT occurs near the end of the first frame - //set_history(d_check_width*2); - - std::stringstream str; - str << name() << unique_id(); - d_me = pmt::pmt_string_to_symbol(str.str()); - d_key = pmt::pmt_string_to_symbol("frame_info"); -} - -int air_modes_framer::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - //do things! - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - //unsigned char *outattrib = (unsigned char *) output_items[0]; - int size = noutput_items - d_check_width*2; - if(size < 0) return 0; - float reference_level; - framer_packet_type packet_attrib; - std::vector tags; - - uint64_t abs_sample_cnt = nitems_read(0); - get_tags_in_range(tags, 0, abs_sample_cnt, abs_sample_cnt + size, pmt::pmt_string_to_symbol("preamble_found")); - std::vector::iterator tag_iter; - - memcpy(out, in, size * sizeof(float)); - - for(tag_iter = tags.begin(); tag_iter != tags.end(); tag_iter++) { - uint64_t i = gr_tags::get_nitems(*tag_iter) - abs_sample_cnt; - //first, assume we have a long packet - packet_attrib = Long_Packet; - - //let's use the preamble marker to get a reference level for the packet - reference_level = (in[i] - + in[i+2] - + in[i+7] - + in[i+9]) / 4.0; - - //armed with our reference level, let's look for marks within 3dB of the reference level in bits 57-62 (65-70, see above) - //if bits 57-62 have marks in either chip, we've got a long packet - //otherwise we have a short packet - //NOTE: you can change the default here to be short packet, and then check for a long packet. don't know which way is better. - for(int j = (65 * d_samples_per_symbol); j < (70 * d_samples_per_symbol); j += d_samples_per_symbol) { - float t_max = std::max(in[i+j], - in[i+j+d_samples_per_chip] - ); - if(t_max < (reference_level / 2.0)) packet_attrib = Short_Packet; - } - - //BUT: we must also loop through the entire packet to make sure it is clear of additional preamble markers! - //if it has another preamble marker, it's been FRUITed, and we must only - //mark the new packet (i.e., just continue). - - int lookahead; - if(packet_attrib == Long_Packet) lookahead = 112 * d_samples_per_symbol; - else lookahead = 56 * d_samples_per_symbol; - - //ok we have to re-do lookahead for this tagged version. - //we can do this by looking for tags that fall within that window - std::vector fruit_tags; - get_tags_in_range(fruit_tags, 0, abs_sample_cnt+i+1, abs_sample_cnt+i+lookahead, pmt::pmt_string_to_symbol("preamble_found")); - if(fruit_tags.size() > 0) packet_attrib = Fruited_Packet; - - //insert tag here - add_item_tag(0, //stream ID - nitems_written(0)+i, //sample - d_key, //frame_info - pmt::pmt_from_long((long)packet_attrib), - d_me //block src id - ); - } - - return size; -} diff --git a/src/lib/air_modes_framer.h b/src/lib/air_modes_framer.h deleted file mode 100644 index 067a09c..0000000 --- a/src/lib/air_modes_framer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -# Copyright 2010 Nick Foster -# -# This file is part of gr-air-modes -# -# gr-air-modes 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. -# -# gr-air-modes 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 gr-air-modes; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# -*/ - -#ifndef INCLUDED_AIR_MODES_FRAMER_H -#define INCLUDED_AIR_MODES_FRAMER_H - -#include - -class air_modes_framer; -typedef boost::shared_ptr air_modes_framer_sptr; - -air_modes_framer_sptr air_make_modes_framer(int channel_rate); - -/*! - * \brief mode select framer detection - * \ingroup block - */ -class air_modes_framer : public gr_sync_block -{ -private: - friend air_modes_framer_sptr air_make_modes_framer(int channel_rate); - air_modes_framer(int channel_rate); - - int d_check_width; - int d_chip_rate; - int d_samples_per_chip; - int d_samples_per_symbol; - pmt::pmt_t d_me, d_key; - -public: - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - - -#endif /* INCLUDED_AIR_MODES_framer_H */ diff --git a/src/lib/air_modes_slicer.cc b/src/lib/air_modes_slicer.cc index 70023d0..a3e943a 100644 --- a/src/lib/air_modes_slicer.cc +++ b/src/lib/air_modes_slicer.cc @@ -212,7 +212,7 @@ int air_modes_slicer::work(int noutput_items, rx_packet.message_type = (rx_packet.data[0] >> 3) & 0x1F; //get the message type for the parser to conveniently use, and to make decisions on ECC methods - if(rx_packet.type == Short_Packet && rx_packet.message_type != 11 && rx_packet.numlowconf > 2) {n_loconf++; continue;} + if(rx_packet.type == Short_Packet && rx_packet.message_type != 11 && rx_packet.numlowconf > 0) {n_loconf++; continue;} if(rx_packet.message_type == 11 && rx_packet.numlowconf >= 10) {n_loconf++; continue;} rx_packet.parity = modes_check_parity(rx_packet.data, packet_length); diff --git a/src/lib/modes_parity.cc b/src/lib/modes_parity.cc index cd3c0a0..3a8f578 100644 --- a/src/lib/modes_parity.cc +++ b/src/lib/modes_parity.cc @@ -176,84 +176,3 @@ int modes_check_parity(unsigned char data[], int length) else return short_crc; } -bruteResultTypeDef modes_ec_brute(modes_packet &err_packet) -{ - //here we basically crib EC's air_ms_ec_brute algorithm, because wherever he got it, it's perfect, and that comparison thing is fast to boot. - //we assume that the syndrome result has already been calculated - //how many bits shall we attempt to flip? let's say a max of 8 bits, to start. remember we're only going after long packets here. - - //well, in practice, you almost never successfully recover a packet with more than 4 LCBs. so let's put the limit there to save wasting CPU time - //on hopeless packets. - - //want to speed things up? instead of going through the "search codes" in numeric order, let's find a way to order them probablistically. - //that is, right now, EC's algorithm uses a "search order" which starts with ALL possible low-confidence bits flipped, and goes down counting in binary. - //statistically it's far more likely that a single bit was flipped somewhere, so we should go through those codes first. THEN we move on to two bits flipped, and so on. - - if(err_packet.parity == 0) return No_Error; - if(err_packet.numlowconf > 4) return Too_Many_LCBs; - if(err_packet.type != Long_Packet) return No_Solution; - - unsigned crc; - unsigned answer; - unsigned found = 0; - //so in order for this to work, we need the positions of the LCBs. should we be calculating these as we go? ok, done. - - unsigned lastone = (1 << err_packet.numlowconf) - 1; - -// int numflipped; //for debugging - - //here it would be a little faster if we ran through the parity table looking for single-bit errors. then we could start - //the loop at i=2 instead. - - for(int i = 1; i <= err_packet.numlowconf; i++) { - unsigned j = (1 << i) - 1; - while(j < lastone) { - crc = 0; - //calc syndrome - for(int k = 0; k < err_packet.numlowconf; k++) { - if((j >> k) & 1) crc ^= modes_parity_table[err_packet.lowconfbits[k]]; - } - //then test - if(crc == err_packet.parity) { - answer = j; - found++; - if(found > 1) break; - } - //then increment - j = next_set_of_n_elements(j); - } - if(found > 1) break; - } - if(found > 1) return Multiple_Solutions; - else if(found == 1) { - //fix the packet, verify the CRC, and return - //the bits that need to be flipped are in answer. -// numflipped=0; //just for debugging, so i can see - for(int i = 0; i < err_packet.numlowconf; i++) { - if( (answer >> i) & 1) { -// numflipped++; - unsigned mask = 1 << (7 - (err_packet.lowconfbits[i] % 8)); //create a bitmask - err_packet.data[err_packet.lowconfbits[i]/8] ^= mask; //flip the bit - } - } - //printf("Flipped %i bits\n", numflipped); - err_packet.parity = 0; //since you found it - return Solution_Found; - - } else return No_Solution; -} - - -//from hackersdelight. given a number with x bits set, gives you the next number in that set. -unsigned next_set_of_n_elements(unsigned x) -{ - unsigned smallest, ripple, new_smallest, ones; - - if (x == 0) return 0; - smallest = (x & -x); - ripple = x + smallest; - new_smallest = (ripple & -ripple); - ones = ((new_smallest/smallest) >> 1) - 1; - return ripple | ones; -} -