diff --git a/CMakeLists.txt b/CMakeLists.txt index e5bb48a..e1d26ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,7 +108,7 @@ add_custom_target(uninstall ######################################################################## # Add subdirectories ######################################################################## -add_subdirectory(include) +add_subdirectory(include/gr_air_modes) add_subdirectory(lib) add_subdirectory(swig) add_subdirectory(python) diff --git a/apps/modes_gui b/apps/modes_gui index 161bba6..b36ea96 100755 --- a/apps/modes_gui +++ b/apps/modes_gui @@ -137,6 +137,10 @@ class mainwindow(QtGui.QMainWindow): self.ui.list_aircraft.selectionModel().currentRowChanged.connect(self.update_map_highlight) self.datamodel.dataChanged.connect(self.unmapped_widgets_dataChanged) + #hook up parameter-changed signals so we can change gain, rate, etc. while running + self.ui.combo_rate.currentIndexChanged['QString'].connect(self.update_sample_rate) +# self.ui. + #hook up live data text box update signal self.live_data_changed_signal.connect(self.on_append_live_data) @@ -145,6 +149,10 @@ class mainwindow(QtGui.QMainWindow): self.prefs = None + def update_sample_rate(self, rate): + if self.running: + self._radio.set_rate(int(float(rate)*1e6)) + ############ widget update functions for non-mapped widgets ############ def update_heading_widget(self, index): if index.model() is not None: diff --git a/apps/modes_rx b/apps/modes_rx index 047e1e9..24de121 100755 --- a/apps/modes_rx +++ b/apps/modes_rx @@ -86,8 +86,9 @@ def main(): sbs1port = air_modes.output_sbs1(cpr_dec, 30003, publisher) tb.run() + time.sleep(0.2) tb.close() - + time.sleep(0.2) relay.close() if options.kml is not None: diff --git a/include/air_modes_int_and_dump.h b/include/air_modes_int_and_dump.h deleted file mode 100644 index d7e519d..0000000 --- a/include/air_modes_int_and_dump.h +++ /dev/null @@ -1,54 +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_int_and_dump_H -#define INCLUDED_AIR_MODES_int_and_dump_H - -#include - -class air_modes_int_and_dump; -typedef boost::shared_ptr air_modes_int_and_dump_sptr; - -air_modes_int_and_dump_sptr air_make_modes_int_and_dump(int samples_per_chip); - -/*! - * \brief mode select int_and_dump filter - * \ingroup block - */ -class air_modes_int_and_dump : public gr_block -{ -private: - friend air_modes_int_and_dump_sptr air_make_modes_int_and_dump(int samples_per_chip); - air_modes_int_and_dump(int samples_per_chip); - - int d_samples_per_chip; - float d_acc; - float d_pos; - -public: - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_AIR_MODES_int_and_dump_H */ diff --git a/include/air_modes_preamble.h b/include/air_modes_preamble.h deleted file mode 100644 index 7a0994b..0000000 --- a/include/air_modes_preamble.h +++ /dev/null @@ -1,66 +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_PREAMBLE_H -#define INCLUDED_AIR_MODES_PREAMBLE_H - -#include -#include - -class air_modes_preamble; -typedef boost::shared_ptr air_modes_preamble_sptr; - -AIR_MODES_API air_modes_preamble_sptr air_make_modes_preamble(int channel_rate, float threshold_db); - -/*! - * \brief mode select preamble detection - * \ingroup block - */ -class AIR_MODES_API air_modes_preamble : public gr::block -{ -private: - friend air_modes_preamble_sptr air_make_modes_preamble(int channel_rate, float threshold_db); - air_modes_preamble(int channel_rate, float threshold_db); - - int d_check_width; - int d_chip_rate; - float d_preamble_length_us; - int d_samples_per_chip; - int d_samples_per_symbol; - float d_threshold_db; - float d_threshold; - pmt::pmt_t d_me, d_key; - gr::tag_t d_timestamp; - double d_secs_per_sample; - -public: - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - void set_rate(int channel_rate); - void set_threshold(float threshold_db); - float get_threshold(void); -}; - -#endif /* INCLUDED_AIR_MODES_PREAMBLE_H */ diff --git a/include/CMakeLists.txt b/include/gr_air_modes/CMakeLists.txt similarity index 88% rename from include/CMakeLists.txt rename to include/gr_air_modes/CMakeLists.txt index 38c5ac3..09254ca 100644 --- a/include/CMakeLists.txt +++ b/include/gr_air_modes/CMakeLists.txt @@ -21,9 +21,9 @@ # Install public header files ######################################################################## install(FILES - air_modes_preamble.h - air_modes_slicer.h - air_modes_types.h - air_modes_api.h - DESTINATION include/gr-air-modes + preamble.h + slicer.h + types.h + api.h + DESTINATION include/gr_air_modes ) diff --git a/include/air_modes_api.h b/include/gr_air_modes/api.h similarity index 100% rename from include/air_modes_api.h rename to include/gr_air_modes/api.h diff --git a/include/modes_crc.h b/include/gr_air_modes/modes_crc.h similarity index 100% rename from include/modes_crc.h rename to include/gr_air_modes/modes_crc.h diff --git a/include/gr_air_modes/preamble.h b/include/gr_air_modes/preamble.h new file mode 100644 index 0000000..a07022c --- /dev/null +++ b/include/gr_air_modes/preamble.h @@ -0,0 +1,51 @@ +/* +# Copyright 2013 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_PREAMBLE_H +#define INCLUDED_AIR_MODES_PREAMBLE_H + +#include +#include + +namespace gr { +namespace air_modes { + +/*! + * \brief mode select preamble detection + * \ingroup block + */ +class AIR_MODES_API preamble : virtual public gr::block +{ +public: + typedef boost::shared_ptr sptr; + static sptr make(int channel_rate, float threshold_db); + + virtual void set_rate(int channel_rate) = 0; + virtual void set_threshold(float threshold_db) = 0; + virtual int get_rate(void) = 0; + virtual float get_threshold(void) = 0; +}; + +} // namespace air_modes +} // namespace gr + +#endif /* INCLUDED_AIR_MODES_PREAMBLE_H */ diff --git a/include/gr_air_modes/slicer.h b/include/gr_air_modes/slicer.h new file mode 100644 index 0000000..4813c81 --- /dev/null +++ b/include/gr_air_modes/slicer.h @@ -0,0 +1,47 @@ +/* +# Copyright 2013 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_SLICER_H +#define INCLUDED_AIR_MODES_SLICER_H + +#include +#include +#include + +namespace gr { +namespace air_modes { + +/*! + * \brief mode select slicer + * \ingroup block + */ +class AIR_MODES_API slicer : virtual public gr::sync_block +{ +public: + typedef boost::shared_ptr sptr; + static sptr make(gr::msg_queue::sptr queue); +}; + +} //namespace air_modes +} //namespace gr + +#endif /* INCLUDED_AIR_MODES_SLICER_H */ diff --git a/include/air_modes_types.h b/include/gr_air_modes/types.h similarity index 100% rename from include/air_modes_types.h rename to include/gr_air_modes/types.h diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index fffd623..e3bd53a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -23,8 +23,8 @@ include(GrPlatform) #define LIB_SUFFIX add_library(air_modes SHARED - air_modes_preamble.cc - air_modes_slicer.cc + preamble_impl.cc + slicer_impl.cc modes_crc.cc ) target_link_libraries(air_modes ${Boost_LIBRARIES} ${GNURADIO_RUNTIME_LIBRARIES}) diff --git a/lib/air_modes_int_and_dump.cc b/lib/air_modes_int_and_dump.cc deleted file mode 100644 index 1a4e206..0000000 --- a/lib/air_modes_int_and_dump.cc +++ /dev/null @@ -1,89 +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 - -air_modes_int_and_dump_sptr air_make_modes_int_and_dump(int samples_per_symbol) -{ - return air_modes_int_and_dump_sptr (new air_modes_int_and_dump(samples_per_symbol)); -} - -air_modes_int_and_dump::air_modes_int_and_dump(int samps_per_chip) : - gr_block ("modes_int_and_dump", - gr_make_io_signature (1, 1, sizeof(float)), - gr_make_io_signature (1, 1, sizeof(float))) -{ - d_samples_per_symbol = samples_per_symbol; - set_output_multiple(d_samples_per_symbol); - set_history(d_samples_per_symbol); - - d_acc = 0; - d_pos = 0; -} - -int air_modes_int_and_dump::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - int input_items = std::min(ninput_items[0], ninput_items[1]); //just in case - - //ok first of all we look for "preamble_found" tags in our input range. - //get a vector of these tags, then every time we hit one - //reset the integrator position and accumulator - std::vector tags; - uint64_t abs_sample_cnt = nitems_read(0); - get_tags_in_range(tags, 0, abs_sample_cnt, abs_sample_cnt + ninput_items, pmt::pmt_string_to_symbol("preamble_found")); - - int out_items = 0; - - int offset = gr_tags::get_nitems(&tags[0]) - abs_sample_cnt; - - for(int i=0; i<120*2; i++) { //for each symbol in a potential long packet - out[out_items] = 0; - for(int j=0; j -#include -#include +#include +#include #include #include diff --git a/lib/air_modes_preamble.cc b/lib/preamble_impl.cc similarity index 89% rename from lib/air_modes_preamble.cc rename to lib/preamble_impl.cc index 0c3c8d2..d367c98 100644 --- a/lib/air_modes_preamble.cc +++ b/lib/preamble_impl.cc @@ -26,38 +26,55 @@ #endif #include -#include +#include "preamble_impl.h" #include #include #include #include -air_modes_preamble_sptr air_make_modes_preamble(int channel_rate, float threshold_db) -{ - return air_modes_preamble_sptr (new air_modes_preamble(channel_rate, threshold_db)); +namespace gr { + +air_modes::preamble::sptr air_modes::preamble::make(int channel_rate, float threshold_db) { + return gnuradio::get_initial_sptr(new air_modes::preamble_impl(channel_rate, threshold_db)); } -air_modes_preamble::air_modes_preamble(int channel_rate, float threshold_db) : - gr::block ("modes_preamble", +air_modes::preamble_impl::preamble_impl(int channel_rate, float threshold_db) : + gr::block ("preamble", gr::io_signature::make2 (2, 2, sizeof(float), sizeof(float)), //stream 0 is received data, stream 1 is moving average for reference - gr::io_signature::make (1, 1, sizeof(float))) //the output packets + gr::io_signature::make (1, 1, sizeof(float))) //the output soft symbols { 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; //only search to this far from the end of the stream buffer - d_threshold_db = threshold_db; - d_threshold = powf(10., threshold_db/20.); //the level that the sample must be above the moving average in order to qualify as a pulse - d_secs_per_sample = 1.0 / channel_rate; - set_output_multiple(1+d_check_width*2); - + set_rate(channel_rate); + set_threshold(threshold_db); + std::stringstream str; str << name() << unique_id(); d_me = pmt::string_to_symbol(str.str()); d_key = pmt::string_to_symbol("preamble_found"); +} + +void air_modes::preamble_impl::set_rate(int channel_rate) { + d_samples_per_chip = channel_rate / d_chip_rate; + d_samples_per_symbol = d_samples_per_chip * 2; + d_check_width = 120 * d_samples_per_symbol; + d_secs_per_sample = 1.0/channel_rate; + set_output_multiple(1+d_check_width*2); set_history(d_samples_per_symbol); } +void air_modes::preamble_impl::set_threshold(float threshold_db) { + d_threshold_db = threshold_db; + d_threshold = powf(10., threshold_db/20.); //the level that the sample must be above the moving average in order to qualify as a pulse +} + +float air_modes::preamble_impl::get_threshold(void) { + return d_threshold_db; +} + +int air_modes::preamble_impl::get_rate(void) { + return d_samples_per_chip * d_chip_rate; +} + static void integrate_and_dump(float *out, const float *in, int chips, int samps_per_chip) { for(int i=0; i +#include +#include + +namespace gr { +namespace air_modes { + +class AIR_MODES_API preamble_impl : public preamble +{ +private: + int d_check_width; + int d_chip_rate; + float d_preamble_length_us; + int d_samples_per_chip; + int d_samples_per_symbol; + float d_threshold_db; + float d_threshold; + pmt::pmt_t d_me, d_key; + gr::tag_t d_timestamp; + double d_secs_per_sample; + +public: + preamble_impl(int channel_rate, float threshold_db); + + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void set_rate(int channel_rate); + void set_threshold(float threshold_db); + float get_threshold(void); + int get_rate(void); +}; + +} //namespace air_modes +} //namespace gr + +#endif //_AIR_MODES_PREAMBLE_IMPL_H_ diff --git a/lib/air_modes_slicer.cc b/lib/slicer_impl.cc similarity index 87% rename from lib/air_modes_slicer.cc rename to lib/slicer_impl.cc index 720e107..484a14e 100644 --- a/lib/air_modes_slicer.cc +++ b/lib/slicer_impl.cc @@ -26,12 +26,12 @@ #endif #include -#include +#include "slicer_impl.h" #include -#include +#include #include #include -#include +#include #include #include @@ -41,14 +41,15 @@ extern "C" #include } -air_modes_slicer_sptr air_make_modes_slicer(int channel_rate, gr::msg_queue::sptr queue) -{ - return air_modes_slicer_sptr (new air_modes_slicer(channel_rate, queue)); +namespace gr { + +air_modes::slicer::sptr air_modes::slicer::make(gr::msg_queue::sptr queue) { + return gnuradio::get_initial_sptr(new air_modes::slicer_impl(queue)); } -air_modes_slicer::air_modes_slicer(int channel_rate, gr::msg_queue::sptr queue) : - gr::sync_block ("modes_slicer", - gr::io_signature::make (1, 1, sizeof(float)), //stream 0 is received data, stream 1 is binary preamble detector output +air_modes::slicer_impl::slicer_impl(gr::msg_queue::sptr queue) : + gr::sync_block ("slicer", + gr::io_signature::make (1, 1, sizeof(float)), gr::io_signature::make (0, 0, 0) ) { //initialize private data here @@ -63,13 +64,13 @@ air_modes_slicer::air_modes_slicer(int channel_rate, gr::msg_queue::sptr queue) //this slicer is courtesy of Lincoln Labs. supposedly it is more resistant to mode A/C FRUIT. //see http://adsb.tc.faa.gov/WG3_Meetings/Meeting8/Squitter-Lon.pdf -static slice_result_t slicer(const float bit0, const float bit1, const float ref) { +static slice_result_t llslicer(const float bit0, const float bit1, const float ref) { slice_result_t result; //3dB limits for bit slicing and confidence measurement float highlimit=ref*1.414; float lowlimit=ref*0.707; - + bool firstchip_inref = ((bit0 > lowlimit) && (bit0 < highlimit)); bool secondchip_inref = ((bit1 > lowlimit) && (bit1 < highlimit)); @@ -98,7 +99,7 @@ static slice_result_t slicer(const float bit0, const float bit1, const float ref return result; } -int air_modes_slicer::work(int noutput_items, +int air_modes::slicer_impl::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { @@ -106,7 +107,7 @@ int air_modes_slicer::work(int noutput_items, int size = noutput_items - d_check_width; //since it's a sync block, i assume that it runs with ninput_items = noutput_items if(0) std::cout << "Slicer called with " << size << " samples" << std::endl; - + 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::string_to_symbol("preamble_found")); @@ -133,7 +134,7 @@ int air_modes_slicer::work(int noutput_items, //now let's slice the header so we can determine if it's a short pkt or a long pkt unsigned char pkt_hdr = 0; for(int j=0; j < 5; j++) { - slice_result_t slice_result = slicer(in[i+j*2], in[i+j*2+1], rx_packet.reference_level); + slice_result_t slice_result = llslicer(in[i+j*2], in[i+j*2+1], rx_packet.reference_level); if(slice_result.decision) pkt_hdr += 1 << (4-j); } if(pkt_hdr == 16 or pkt_hdr == 17 or pkt_hdr == 20 or pkt_hdr == 21) rx_packet.type = Long_Packet; @@ -143,7 +144,7 @@ int air_modes_slicer::work(int noutput_items, //it's slice time! //TODO: don't repeat your work here, you already have the first 5 bits for(int j = 0; j < packet_length; j++) { - slice_result_t slice_result = slicer(in[i+j*2], in[i+j*2+1], rx_packet.reference_level); + slice_result_t slice_result = llslicer(in[i+j*2], in[i+j*2+1], rx_packet.reference_level); //put the data into the packet if(slice_result.decision) { @@ -156,12 +157,8 @@ int air_modes_slicer::work(int noutput_items, if(rx_packet.numlowconf < 24) rx_packet.lowconfbits[rx_packet.numlowconf++] = j; } } - - /******************** BEGIN TIMESTAMP BS ******************/ + rx_packet.timestamp = pmt::to_double(tag_iter->value); - /******************* END TIMESTAMP BS *********************/ - - //increment for the next round //here you might want to traverse the whole packet and if you find all 0's, just toss it. don't know why these packets turn up, but they pass ECC. bool zeroes = 1; @@ -174,7 +171,7 @@ int air_modes_slicer::work(int noutput_items, if(rx_packet.type == Short_Packet && rx_packet.message_type != 11 && rx_packet.numlowconf > 0) {continue;} if(rx_packet.message_type == 11 && rx_packet.numlowconf >= 10) {continue;} - + rx_packet.crc = modes_check_crc(rx_packet.data, packet_length); //crc for packets that aren't type 11 or type 17 is encoded with the transponder ID, which we don't know @@ -195,3 +192,5 @@ int air_modes_slicer::work(int noutput_items, if(0) std::cout << "Slicer consumed " << size << ", returned " << size << std::endl; return size; } + +} //namespace gr diff --git a/include/air_modes_slicer.h b/lib/slicer_impl.h similarity index 63% rename from include/air_modes_slicer.h rename to lib/slicer_impl.h index 8915d0c..bfdf3de 100644 --- a/include/air_modes_slicer.h +++ b/lib/slicer_impl.h @@ -1,5 +1,5 @@ /* -# Copyright 2010 Nick Foster +# Copyright 2013 Nick Foster # # This file is part of gr-air-modes # @@ -20,28 +20,20 @@ # */ -#ifndef INCLUDED_AIR_MODES_slicer_H -#define INCLUDED_AIR_MODES_slicer_H +#ifndef INCLUDED_AIR_MODES_SLICER_IMPL_H +#define INCLUDED_AIR_MODES_SLICER_IMPL_H #include #include -#include +#include +#include -class air_modes_slicer; -typedef boost::shared_ptr air_modes_slicer_sptr; +namespace gr { +namespace air_modes { -AIR_MODES_API air_modes_slicer_sptr air_make_modes_slicer(int channel_rate, gr::msg_queue::sptr queue); - -/*! - * \brief mode select slicer detection - * \ingroup block - */ -class AIR_MODES_API air_modes_slicer : public gr::sync_block +class AIR_MODES_API slicer_impl : public slicer { private: - friend air_modes_slicer_sptr air_make_modes_slicer(int channel_rate, gr::msg_queue::sptr queue); - air_modes_slicer(int channel_rate, gr::msg_queue::sptr queue); - int d_check_width; int d_chip_rate; int d_samples_per_chip; @@ -50,9 +42,14 @@ private: std::ostringstream d_payload; public: + slicer_impl(gr::msg_queue::sptr queue); + int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); }; -#endif /* INCLUDED_AIR_MODES_slicer_H */ +} //namespace air_modes +} //namespace gr + +#endif /* INCLUDED_AIR_MODES_SLICER_IMPL_H */ diff --git a/python/get_uniq.py b/python/get_uniq.py new file mode 100755 index 0000000..c7bf5fe --- /dev/null +++ b/python/get_uniq.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +import sys, re + +if __name__== '__main__': + data = sys.stdin.readlines() + icaos = [] + num_icaos = 0 + for line in data: + match = re.match(".*from (\w+)", line) + if match is not None: + icao = int(match.group(1), 16) + icaos.append(icao) + + #get dupes + dupes = sorted([icao for icao in set(icaos) if icaos.count(icao) > 1]) + for icao in dupes: + print "%x" % icao + print "Found non-unique replies from %i aircraft" % len(dupes) + + diff --git a/python/mlat_client.py b/python/mlat_client.py new file mode 100644 index 0000000..3111b61 --- /dev/null +++ b/python/mlat_client.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# +# Copyright 2012 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. +# + +#multilateration client +#outputs stamps to server, receives multilaterated outputs back + +import socket, pickle, time, sys +import air_modes +from gnuradio import gr + +pickle_prot = 0 +#pickle_prot = pickle.HIGHEST_PROTOCOL + +class client_info: + def __init__(self): + self.name = "" + self.position = [] + self.offset_secs = 0 + self.offset_frac_secs = 0.0 + self.time_source = None + +class mlat_client: + def __init__(self, queue, position, server_addr, time_source): + self._queue = queue + self._pos = position + self._name = socket.gethostname() + #connect to server + self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._sock.setblocking(1) + self._sock.connect((server_addr, 19005)) + info = client_info() + info.name = self._name + info.position = self._pos + info.time_source = time_source #"gpsdo" or None + self._sock.send(pickle.dumps(info)) + reply = self._sock.recv(1024) + if reply != "HELO": #i know, shut up + raise Exception("Invalid reply from server: %s" % reply) + self._sock.setblocking(0) + self._remnant = None + + def __del__(self): + self._sock.close() + + #send a stamped report to the server + def output(self, message): + self._sock.send(message+"\n") + + #this is called from the update() method list of the main app thread + def get_mlat_positions(self): + msg = None + try: + msg = self._sock.recv(1024) + except socket.error: + pass + if msg: + for line in msg.splitlines(True): + if line.endswith("\n"): + if self._remnant: + line = self._remnant + line + self._remnant = None + self._queue.insert_tail(gr.message_from_string(line)) + + else: + if self._remnant is not None: + raise Exception("Malformed data: " + line) + else: + self._remnant = line diff --git a/python/mlat_types.py b/python/mlat_types.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/python/mlat_types.py @@ -0,0 +1 @@ + diff --git a/python/radio.py b/python/radio.py index 02b5ac0..da0c6b0 100644 --- a/python/radio.py +++ b/python/radio.py @@ -113,13 +113,17 @@ class modes_radio (gr.top_block, pubsub): return self._options.source is 'uhd' or self._options.source is 'osmocom' def set_freq(self, freq): - return self._u.set_center_freq(freq, 0) if live_source() else 0 + return self._u.set_center_freq(freq, 0) if self.live_source() else 0 def set_gain(self, gain): - return self._u.set_gain(gain) if live_source() else 0 + return self._u.set_gain(gain) if self.live_source() else 0 def set_rate(self, rate): - return self._u.set_rate(rate) if live_source() else 0 + self._rx_path.set_rate(rate) + return self._u.set_rate(rate) if self.live_source() else 0 + + def set_threshold(self, threshold): + self._rx_path.set_threshold(threshold) def get_freq(self, freq): return self._u.get_center_freq(freq, 0) if live_source() else 1090e6 diff --git a/python/rx_path.py b/python/rx_path.py index b28600a..e778d04 100644 --- a/python/rx_path.py +++ b/python/rx_path.py @@ -48,10 +48,10 @@ class rx_path(gr.hier_block2): self._avg = blocks.moving_average_ff(48*self._spc, 1.0/(48*self._spc))#, self._rate) # 3 preambles # Synchronize to Mode-S preamble - self._sync = air_modes_swig.modes_preamble(self._rate, self._threshold) + self._sync = air_modes_swig.preamble(self._rate, self._threshold) # Slice Mode-S bits and send to message queue - self._slicer = air_modes_swig.modes_slicer(self._rate, self._queue) + self._slicer = air_modes_swig.slicer(self._queue) # Wire up the flowgraph self.connect(self, self._demod) @@ -61,7 +61,6 @@ class rx_path(gr.hier_block2): def set_rate(self, rate): self._sync.set_rate(rate) - self._slicer.set_rate(rate) self._spc = int(rate/2e6) self._avg.set_length_and_scale(48*self._spc, 1.0/(48*self._spc)) if self._bb != self._demod: @@ -79,4 +78,4 @@ class rx_path(gr.hier_block2): def get_threshold(self, threshold): return self._sync.get_threshold() - + diff --git a/swig/air_modes.i b/swig/air_modes.i index 556f6d6..6f5a42b 100644 --- a/swig/air_modes.i +++ b/swig/air_modes.i @@ -1,45 +1,17 @@ /* -*- c++ -*- */ -%include "gnuradio.i" // the common stuff +#define AIR_MODES_API + +%include "gnuradio.i" %{ -#include "air_modes_preamble.h" -#include "air_modes_slicer.h" -#include +#include "gr_air_modes/preamble.h" +#include "gr_air_modes/slicer.h" %} -// ---------------------------------------------------------------- - -/* - * First arg is the package prefix. - * Second arg is the name of the class minus the prefix. - * - * This does some behind-the-scenes magic so we can - * access howto_square_ff from python as howto.square_ff - */ -GR_SWIG_BLOCK_MAGIC(air,modes_preamble); - -air_modes_preamble_sptr air_make_modes_preamble (int channel_rate, float threshold_db); - -class air_modes_preamble : public gr::sync_block -{ - set_rate(int channel_rate); - set_threshold(float threshold_db); - int get_threshold(void); -private: - air_modes_preamble (int channel_rate, float threshold_db); -}; - -GR_SWIG_BLOCK_MAGIC(air,modes_slicer); - -air_modes_slicer_sptr air_make_modes_slicer (int channel_rate, gr::msg_queue::sptr queue); - -class air_modes_slicer : public gr::block -{ - set_rate(int channel_rate); -private: - air_modes_slicer (int channel_rate, gr::msg_queue::sptr queue); -}; +%include "gr_air_modes/preamble.h" +%include "gr_air_modes/slicer.h" -// ---------------------------------------------------------------- +GR_SWIG_BLOCK_MAGIC2(air_modes,preamble); +GR_SWIG_BLOCK_MAGIC2(air_modes,slicer);