diff -Nru gnuradio-3.7.10.1/debian/changelog gnuradio-3.7.10.1/debian/changelog --- gnuradio-3.7.10.1/debian/changelog 2016-08-27 04:06:08.000000000 +0000 +++ gnuradio-3.7.10.1/debian/changelog 2017-01-31 01:09:05.000000000 +0000 @@ -1,3 +1,16 @@ +gnuradio (3.7.10.1-2~ubuntu16.10.1~ppa1) yakkety; urgency=medium + + * No-change backport to yakkety + + -- Alexandru Csete Tue, 31 Jan 2017 02:09:05 +0100 + +gnuradio (3.7.10.1-2) unstable; urgency=medium + + * update to v3.7.10.1-24-gea2aeca + * add freedvapi blocks + + -- A. Maitland Bottoms Sun, 09 Oct 2016 22:16:42 -0400 + gnuradio (3.7.10.1-1) unstable; urgency=medium * New upstream release diff -Nru gnuradio-3.7.10.1/debian/patches/0007-gr-dtv-Delete-incorrect-assert-and-useless-set_relat.patch gnuradio-3.7.10.1/debian/patches/0007-gr-dtv-Delete-incorrect-assert-and-useless-set_relat.patch --- gnuradio-3.7.10.1/debian/patches/0007-gr-dtv-Delete-incorrect-assert-and-useless-set_relat.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0007-gr-dtv-Delete-incorrect-assert-and-useless-set_relat.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,34 @@ +From d7674ce11c5d3665384ead29590a875df90d9bbf Mon Sep 17 00:00:00 2001 +From: Ron Economos +Date: Fri, 2 Sep 2016 06:48:44 -0700 +Subject: [PATCH 07/20] gr-dtv: Delete incorrect assert() and useless + set_relative_rate(). + +--- + gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc +index 05554c5..d170e3f 100644 +--- a/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc ++++ b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc +@@ -1,6 +1,6 @@ + /* -*- c++ -*- */ + /* +- * Copyright 2015 Free Software Foundation, Inc. ++ * Copyright 2015,2016 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -578,8 +578,6 @@ namespace gr { + * + * out/in rate is therefore km/8n in bytes + */ +- assert((d_k * d_m) % (8 * d_n) == 0); +- set_relative_rate((d_k * d_m) / (8 * d_n)); + + assert ((d_bsize * d_n) % d_m == 0); + set_output_multiple (d_bsize * d_k / 8); +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0008-grc-backwards-compatibility-fix-for-pygtk-2.16-cento.patch gnuradio-3.7.10.1/debian/patches/0008-grc-backwards-compatibility-fix-for-pygtk-2.16-cento.patch --- gnuradio-3.7.10.1/debian/patches/0008-grc-backwards-compatibility-fix-for-pygtk-2.16-cento.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0008-grc-backwards-compatibility-fix-for-pygtk-2.16-cento.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,59 @@ +From 3406fb5e2e559875fda527429d4ab8ff9fbf6e90 Mon Sep 17 00:00:00 2001 +From: Michael De Nil +Date: Fri, 9 Sep 2016 11:09:37 -0700 +Subject: [PATCH 08/20] grc: backwards compatibility fix for pygtk 2.16 + (centos6) + +--- + grc/gui/MainWindow.py | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py +index 1437391..686e73c 100644 +--- a/grc/gui/MainWindow.py ++++ b/grc/gui/MainWindow.py +@@ -197,26 +197,35 @@ class MainWindow(gtk.Window): + # to be hidden as well. + + if panel == self.BLOCKS: +- self.btwin.set_visible(visibility) ++ if visibility: ++ self.btwin.show() ++ else: ++ self.btwin.hide() + elif panel == self.CONSOLE: +- self.console_window.set_visible(visibility) ++ if visibility: ++ self.console_window.show() ++ else: ++ self.console_window.hide() + elif panel == self.VARIABLES: +- self.vars.set_visible(visibility) ++ if visibility: ++ self.vars.show() ++ else: ++ self.vars.hide() + else: + return + + if self.variable_panel_sidebar: + # If both the variable editor and block panels are hidden, hide the right container +- if not self.btwin.get_visible() and not self.vars.get_visible(): ++ if not (self.btwin.get_property('visible')) and not (self.vars.get_property('visible')): + self.right.hide() + else: + self.right.show() + else: +- if not self.btwin.get_visible(): ++ if not (self.btwin.get_property('visible')): + self.right.hide() + else: + self.right.show() +- if not self.vars.get_visible() and not self.console_window.get_visible(): ++ if not (self.vars.get_property('visible')) and not (self.console_window.get_property('visible')): + self.left_subpanel.hide() + else: + self.left_subpanel.show() +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0009-uhd-Fix-order-of-include-dirs.patch gnuradio-3.7.10.1/debian/patches/0009-uhd-Fix-order-of-include-dirs.patch --- gnuradio-3.7.10.1/debian/patches/0009-uhd-Fix-order-of-include-dirs.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0009-uhd-Fix-order-of-include-dirs.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,50 @@ +From 7ad6ff1b3e3d6d078ad7fb223faa72b36d311d37 Mon Sep 17 00:00:00 2001 +From: Martin Braun +Date: Thu, 15 Sep 2016 15:01:48 -0600 +Subject: [PATCH 09/20] uhd: Fix order of include dirs + +Boost_INCLUDE_DIRS could previously "undo" UHD_INCLUDE_DIRS if it +pointed to the same location as a UHD installation that was *not* +selected via UHD_INCLUDE_DIRS. +--- + gr-uhd/lib/CMakeLists.txt | 2 +- + gr-uhd/swig/CMakeLists.txt | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gr-uhd/lib/CMakeLists.txt b/gr-uhd/lib/CMakeLists.txt +index b57b80b..b30a0d6 100644 +--- a/gr-uhd/lib/CMakeLists.txt ++++ b/gr-uhd/lib/CMakeLists.txt +@@ -21,12 +21,12 @@ + # Setup the include and linker paths + ######################################################################## + include_directories( ++ ${UHD_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${GR_UHD_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${LOG4CXX_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} +- ${UHD_INCLUDE_DIRS} + ) + + link_directories( +diff --git a/gr-uhd/swig/CMakeLists.txt b/gr-uhd/swig/CMakeLists.txt +index ef54761..163ca8f 100644 +--- a/gr-uhd/swig/CMakeLists.txt ++++ b/gr-uhd/swig/CMakeLists.txt +@@ -26,10 +26,10 @@ include(GrSwig) + set(GR_SWIG_FLAGS -DGR_HAVE_UHD) #needed to parse uhd_swig.i + + set(GR_SWIG_INCLUDE_DIRS ++ ${UHD_INCLUDE_DIRS} + ${GR_UHD_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_SWIG_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} +- ${UHD_INCLUDE_DIRS} + ) + + if(ENABLE_GR_CTRLPORT) +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0010-qtgui-Fix-bug-in-trackerText-for-Frequency-Sink.patch gnuradio-3.7.10.1/debian/patches/0010-qtgui-Fix-bug-in-trackerText-for-Frequency-Sink.patch --- gnuradio-3.7.10.1/debian/patches/0010-qtgui-Fix-bug-in-trackerText-for-Frequency-Sink.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0010-qtgui-Fix-bug-in-trackerText-for-Frequency-Sink.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,26 @@ +From 1f168517ca3a24e1d6647eb523d4163a2d425c8c Mon Sep 17 00:00:00 2001 +From: Tobias Blomberg +Date: Fri, 16 Sep 2016 11:32:48 -0600 +Subject: [PATCH 10/20] qtgui: Fix bug in trackerText for Frequency Sink + +Next to the cursor in the QT GUI Frequency Sink, the Y axis unit label (usually +dB) is shown instead of the X axis label (kHz, MHz etc). +--- + gr-qtgui/lib/FrequencyDisplayPlot.cc | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/gr-qtgui/lib/FrequencyDisplayPlot.cc b/gr-qtgui/lib/FrequencyDisplayPlot.cc +index 233c786..2820bae 100644 +--- a/gr-qtgui/lib/FrequencyDisplayPlot.cc ++++ b/gr-qtgui/lib/FrequencyDisplayPlot.cc +@@ -607,7 +607,6 @@ FrequencyDisplayPlot::setYLabel(const std::string &label, + if(unit.length() > 0) + l += " (" + unit + ")"; + setAxisTitle(QwtPlot::yLeft, QString(l.c_str())); +- ((FreqDisplayZoomer*)d_zoomer)->setUnitType(unit); + } + + void +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0011-qtgui-Fix-Axis-Labels-checkbox-Control-Panel-checkbo.patch gnuradio-3.7.10.1/debian/patches/0011-qtgui-Fix-Axis-Labels-checkbox-Control-Panel-checkbo.patch --- gnuradio-3.7.10.1/debian/patches/0011-qtgui-Fix-Axis-Labels-checkbox-Control-Panel-checkbo.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0011-qtgui-Fix-Axis-Labels-checkbox-Control-Panel-checkbo.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,68 @@ +From cbc71e7799ca4a41cb140b332444c78f795e18e4 Mon Sep 17 00:00:00 2001 +From: Tobias Blomberg +Date: Fri, 16 Sep 2016 15:22:35 -0600 +Subject: [PATCH 11/20] qtgui: Fix Axis Labels checkbox Control Panel checkbox + sync issue + +The Axis Labels checkbox in the Control Panel for the Frequency Sink did not +synchronize its state with settings in other parts of the block, like initial +settings and center mouse button menu. +--- + gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h | 1 + + gr-qtgui/lib/freqcontrolpanel.cc | 6 ++++++ + gr-qtgui/lib/freqdisplayform.cc | 3 +++ + 3 files changed, 10 insertions(+) + +diff --git a/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h b/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h +index ec3ef6c..548d693 100644 +--- a/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h ++++ b/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h +@@ -45,6 +45,7 @@ public: + public slots: + void notifyAvgSlider(int val); + void toggleGrid(bool en); ++ void toggleAxisLabels(bool en); + void toggleMaxHold(bool en); + void toggleMinHold(bool en); + +diff --git a/gr-qtgui/lib/freqcontrolpanel.cc b/gr-qtgui/lib/freqcontrolpanel.cc +index 9729005..8babdf0 100644 +--- a/gr-qtgui/lib/freqcontrolpanel.cc ++++ b/gr-qtgui/lib/freqcontrolpanel.cc +@@ -229,6 +229,12 @@ FreqControlPanel::toggleGrid(bool en) + } + + void ++FreqControlPanel::toggleAxisLabels(bool en) ++{ ++ d_axislabels_check->setChecked(en); ++} ++ ++void + FreqControlPanel::toggleMaxHold(bool en) + { + d_maxhold_check->setChecked(en); +diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc +index 141df54..21d4330 100644 +--- a/gr-qtgui/lib/freqdisplayform.cc ++++ b/gr-qtgui/lib/freqdisplayform.cc +@@ -177,6 +177,8 @@ FreqDisplayForm::setupControlPanel() + // Connect action items in menu to controlpanel widgets + connect(d_grid_act, SIGNAL(triggered(bool)), + d_controlpanel, SLOT(toggleGrid(bool))); ++ connect(d_axislabelsmenu, SIGNAL(triggered(bool)), ++ d_controlpanel, SLOT(toggleAxisLabels(bool))); + connect(d_sizemenu, SIGNAL(whichTrigger(int)), + d_controlpanel, SLOT(toggleFFTSize(int))); + connect(d_winmenu, SIGNAL(whichTrigger(gr::filter::firdes::win_type)), +@@ -199,6 +201,7 @@ FreqDisplayForm::setupControlPanel() + d_layout->addLayout(d_controlpanel, 0, 1); + + d_controlpanel->toggleGrid(d_grid_act->isChecked()); ++ d_controlpanel->toggleAxisLabels(d_axislabelsmenu->isChecked()); + d_controlpanelmenu->setChecked(true); + d_controlpanel->toggleTriggerMode(getTriggerMode()); + d_controlpanel->toggleMaxHold(d_maxhold_act->isChecked()); +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0012-qtgui-Fix-control-panel-FFT-average-slider-value-syn.patch gnuradio-3.7.10.1/debian/patches/0012-qtgui-Fix-control-panel-FFT-average-slider-value-syn.patch --- gnuradio-3.7.10.1/debian/patches/0012-qtgui-Fix-control-panel-FFT-average-slider-value-syn.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0012-qtgui-Fix-control-panel-FFT-average-slider-value-syn.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,79 @@ +From 3dc29e72f6cedb2b55ffff812e17db4fcbb6b63a Mon Sep 17 00:00:00 2001 +From: Tobias Blomberg +Date: Sun, 18 Sep 2016 17:44:20 +0200 +Subject: [PATCH 12/20] qtgui: Fix control panel FFT average slider value sync + in frequency sink + +The FFT average slider in the control panel was not updated when the FFT +average value changed in other parts of the Frequency Sink block. +--- + gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h | 1 + + gr-qtgui/lib/freqcontrolpanel.cc | 13 ++++++++++++- + gr-qtgui/lib/freqdisplayform.cc | 3 +++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h b/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h +index 548d693..5fb8f46 100644 +--- a/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h ++++ b/gr-qtgui/include/gnuradio/qtgui/freqcontrolpanel.h +@@ -44,6 +44,7 @@ public: + + public slots: + void notifyAvgSlider(int val); ++ void setFFTAverage(float val); + void toggleGrid(bool en); + void toggleAxisLabels(bool en); + void toggleMaxHold(bool en); +diff --git a/gr-qtgui/lib/freqcontrolpanel.cc b/gr-qtgui/lib/freqcontrolpanel.cc +index 8babdf0..c0a8ed4 100644 +--- a/gr-qtgui/lib/freqcontrolpanel.cc ++++ b/gr-qtgui/lib/freqcontrolpanel.cc +@@ -249,12 +249,23 @@ FreqControlPanel::toggleMinHold(bool en) + void + FreqControlPanel::notifyAvgSlider(int val) + { +- float fval = static_cast(val) / (d_slider_max - d_slider_min); ++ float fval = static_cast(val) / (d_slider_max - d_slider_min + 1); + emit signalAvgSlider(fval); + emit signalAvg(true); + } + + void ++FreqControlPanel::setFFTAverage(float val) ++{ ++ int slider_val = static_cast(roundf(val * (d_slider_max - d_slider_min + 1))); ++ if (slider_val > d_slider_max) ++ slider_val = d_slider_max; ++ else if (slider_val < d_slider_min) ++ slider_val = d_slider_min; ++ d_avg_slider->setValue(slider_val); ++} ++ ++void + FreqControlPanel::toggleFFTSize(int val) + { + int index = static_cast(round(logf(static_cast(val))/logf(2.0f))) - 5; +diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc +index 21d4330..6aa4894 100644 +--- a/gr-qtgui/lib/freqdisplayform.cc ++++ b/gr-qtgui/lib/freqdisplayform.cc +@@ -191,6 +191,8 @@ FreqDisplayForm::setupControlPanel() + d_controlpanel, SLOT(toggleMaxHold(bool))); + connect(d_minhold_act, SIGNAL(triggered(bool)), + d_controlpanel, SLOT(toggleMinHold(bool))); ++ connect(d_avgmenu, SIGNAL(whichTrigger(float)), ++ d_controlpanel, SLOT(setFFTAverage(float))); + connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)), + d_controlpanel, SLOT(toggleTriggerMode(gr::qtgui::trigger_mode))); + connect(this, SIGNAL(signalTriggerMode(gr::qtgui::trigger_mode)), +@@ -206,6 +208,7 @@ FreqDisplayForm::setupControlPanel() + d_controlpanel->toggleTriggerMode(getTriggerMode()); + d_controlpanel->toggleMaxHold(d_maxhold_act->isChecked()); + d_controlpanel->toggleMinHold(d_minhold_act->isChecked()); ++ d_controlpanel->setFFTAverage(getFFTAverage()); + + emit signalFFTSize(getFFTSize()); + emit signalFFTWindow(getFFTWindowType()); +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0013-dtv-fixed-usage-of-uninitialized-memory-for-data_siz.patch gnuradio-3.7.10.1/debian/patches/0013-dtv-fixed-usage-of-uninitialized-memory-for-data_siz.patch --- gnuradio-3.7.10.1/debian/patches/0013-dtv-fixed-usage-of-uninitialized-memory-for-data_siz.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0013-dtv-fixed-usage-of-uninitialized-memory-for-data_siz.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,168 @@ +From b8b73e23c5a71ab01b30772daccef6422f6789e5 Mon Sep 17 00:00:00 2001 +From: Johnathan Corgan +Date: Mon, 19 Sep 2016 06:48:08 -0700 +Subject: [PATCH 13/20] dtv: fixed usage of uninitialized memory for data_size. + +* Renamed three member variables to be prefixed by d_ +(as is the convention). + +* Type fixes for int/char mixing. +--- + gr-dtv/lib/atsc/atsc_sync_impl.cc | 42 +++++++++++++++++++-------------------- + gr-dtv/lib/atsc/atsc_sync_impl.h | 10 +++++----- + 2 files changed, 25 insertions(+), 27 deletions(-) + +diff --git a/gr-dtv/lib/atsc/atsc_sync_impl.cc b/gr-dtv/lib/atsc/atsc_sync_impl.cc +index d83bccc..7ecc336 100644 +--- a/gr-dtv/lib/atsc/atsc_sync_impl.cc ++++ b/gr-dtv/lib/atsc/atsc_sync_impl.cc +@@ -1,6 +1,6 @@ + /* -*- c++ -*- */ + /* +- * Copyright 2014 Free Software Foundation, Inc. ++ * Copyright 2014,2016 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * +@@ -35,8 +35,8 @@ namespace gr { + static const double ADJUSTMENT_GAIN = 1.0e-5 / (10 * ATSC_DATA_SEGMENT_LENGTH); + static const int SYMBOL_INDEX_OFFSET = 3; + static const int MIN_SEG_LOCK_CORRELATION_VALUE = 5; +- static const int SSI_MIN = -16; +- static const int SSI_MAX = 15; ++ static const char SSI_MIN = -16; ++ static const char SSI_MAX = 15; + + atsc_sync::sptr + atsc_sync::make(float rate) +@@ -62,9 +62,6 @@ namespace gr { + d_w = d_rx_clock_to_symbol_freq; + d_mu = 0.5; + +- for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++) +- sample_mem[i] = 0; +- + d_timing_adjust = 0; + d_counter = 0; + d_symbol_index = 0; +@@ -72,8 +69,9 @@ namespace gr { + + d_sr = 0; + +- for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++) +- d_integrator[i] = SSI_MIN; ++ memset(d_sample_mem, 0, ATSC_DATA_SEGMENT_LENGTH * sizeof(*d_sample_mem)); // (float)0 = 0x00000000 ++ memset(d_data_mem, 0, ATSC_DATA_SEGMENT_LENGTH * sizeof(*d_data_mem)); // (float)0 = 0x00000000 ++ memset(d_integrator, SSI_MIN, ATSC_DATA_SEGMENT_LENGTH * sizeof(*d_integrator)); // signed char + } + + atsc_sync_impl::~atsc_sync_impl() +@@ -103,7 +101,7 @@ namespace gr { + // amount actually consumed + d_si = 0; + +- for (output_produced = 0; output_produced < noutput_items && (d_si + (int)d_interp.ntaps()) < ninput_items[0];) { ++ for (d_output_produced = 0; d_output_produced < noutput_items && (d_si + (int)d_interp.ntaps()) < ninput_items[0];) { + // First we interpolate a sample from input to work with + interp_sample = d_interp.interpolate(&in[d_si], d_mu); + +@@ -119,7 +117,7 @@ namespace gr { + d_si += d_incr; + + // Remember the sample at this count position +- sample_mem[d_counter] = interp_sample; ++ d_sample_mem[d_counter] = interp_sample; + + // Is the sample positive or negative? + int bit = (interp_sample < 0 ? 0 : 1); +@@ -154,22 +152,22 @@ namespace gr { + d_seg_locked = best_correlation_value >= MIN_SEG_LOCK_CORRELATION_VALUE; + + // the coefficients are -1,-1,+1,+1 +- //d_timing_adjust = sample_mem[best_correlation_index - 3] + +- // sample_mem[best_correlation_index - 2] - +- // sample_mem[best_correlation_index - 1] - +- // sample_mem[best_correlation_index]; ++ //d_timing_adjust = d_sample_mem[best_correlation_index - 3] + ++ // d_sample_mem[best_correlation_index - 2] - ++ // d_sample_mem[best_correlation_index - 1] - ++ // d_sample_mem[best_correlation_index]; + + //printf( "d_timing_adjust = %f\n", d_timing_adjust ); + + int corr_count = best_correlation_index; + +- d_timing_adjust = -sample_mem[corr_count--]; ++ d_timing_adjust = -d_sample_mem[corr_count--]; + if( corr_count < 0 ) corr_count = ATSC_DATA_SEGMENT_LENGTH - 1; +- d_timing_adjust -= sample_mem[corr_count--]; ++ d_timing_adjust -= d_sample_mem[corr_count--]; + if( corr_count < 0 ) corr_count = ATSC_DATA_SEGMENT_LENGTH - 1; +- d_timing_adjust += sample_mem[corr_count--]; ++ d_timing_adjust += d_sample_mem[corr_count--]; + if( corr_count < 0 ) corr_count = ATSC_DATA_SEGMENT_LENGTH - 1; +- d_timing_adjust += sample_mem[corr_count--]; ++ d_timing_adjust += d_sample_mem[corr_count--]; + + d_symbol_index = SYMBOL_INDEX_OFFSET - 1 - best_correlation_index; + if (d_symbol_index < 0) +@@ -183,19 +181,19 @@ namespace gr { + // half full, this is OK becouse the fs_checker will not let packets though + // untill a non-corrupted field packet is found + if( d_seg_locked ) { +- data_mem[d_symbol_index] = interp_sample; ++ d_data_mem[d_symbol_index] = interp_sample; + + if( d_symbol_index >= (ATSC_DATA_SEGMENT_LENGTH - 1) ) + { + for( int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++ ) +- soft_data_segment_out[output_produced].data[i] = data_mem[i]; +- output_produced++; ++ soft_data_segment_out[d_output_produced].data[i] = d_data_mem[i]; ++ d_output_produced++; + } + } + } + + consume_each(d_si); +- return output_produced; ++ return d_output_produced; + + } + +diff --git a/gr-dtv/lib/atsc/atsc_sync_impl.h b/gr-dtv/lib/atsc/atsc_sync_impl.h +index f5e6450..670cb31 100644 +--- a/gr-dtv/lib/atsc/atsc_sync_impl.h ++++ b/gr-dtv/lib/atsc/atsc_sync_impl.h +@@ -1,6 +1,6 @@ + /* -*- c++ -*- */ + /* +- * Copyright 2014 Free Software Foundation, Inc. ++ * Copyright 2014,2016 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * +@@ -44,16 +44,16 @@ namespace gr { + double d_mu; // fractional delay [0,1] + int d_incr; + +- float sample_mem[ATSC_DATA_SEGMENT_LENGTH]; +- float data_mem[ATSC_DATA_SEGMENT_LENGTH]; ++ float d_sample_mem[ATSC_DATA_SEGMENT_LENGTH]; ++ float d_data_mem[ATSC_DATA_SEGMENT_LENGTH]; + + double d_timing_adjust; + int d_counter; // free running mod 832 counter + int d_symbol_index; + bool d_seg_locked; +- int d_sr; // 4 bit shift register ++ unsigned char d_sr; // 4 bit shift register + signed char d_integrator[ATSC_DATA_SEGMENT_LENGTH]; +- int output_produced; ++ int d_output_produced; + + public: + atsc_sync_impl(float rate); +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0014-qtgui-c-example-cmake-fix.patch gnuradio-3.7.10.1/debian/patches/0014-qtgui-c-example-cmake-fix.patch --- gnuradio-3.7.10.1/debian/patches/0014-qtgui-c-example-cmake-fix.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0014-qtgui-c-example-cmake-fix.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,47 @@ +From 7566a55d929eab238c9066572b865164042b2aa0 Mon Sep 17 00:00:00 2001 +From: Bastian Bloessl +Date: Tue, 20 Sep 2016 13:35:10 +0200 +Subject: [PATCH 14/20] qtgui: c++ example cmake fix + +--- + gr-qtgui/examples/c++/CMakeLists.txt | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/gr-qtgui/examples/c++/CMakeLists.txt b/gr-qtgui/examples/c++/CMakeLists.txt +index ad84287..239b5db 100644 +--- a/gr-qtgui/examples/c++/CMakeLists.txt ++++ b/gr-qtgui/examples/c++/CMakeLists.txt +@@ -18,14 +18,14 @@ + # Boston, MA 02110-1301, USA. + + include_directories( +- ${GR_QTGUI_INCLUDE_DIRS} +- ${GR_ANALOG_INCLUDE_DIRS} +- ${GR_FILTER_INCLUDE_DIRS} +- ${GR_BLOCKS_INCLUDE_DIRS} +- ${GR_FFT_INCLUDE_DIRS} +- ${GNURADIO_RUNTIME_INCLUDE_DIRS} +- ${QT_INCLUDE_DIRS} +- ${Boost_INCLUDE_DIRS} ++ ${GR_QTGUI_INCLUDE_DIRS} ++ ${GR_ANALOG_INCLUDE_DIRS} ++ ${GR_FILTER_INCLUDE_DIRS} ++ ${GR_BLOCKS_INCLUDE_DIRS} ++ ${GR_FFT_INCLUDE_DIRS} ++ ${GNURADIO_RUNTIME_INCLUDE_DIRS} ++ ${QT_INCLUDE_DIRS} ++ ${Boost_INCLUDE_DIRS} + ) + + list(APPEND QTGUI_LIBRARIES +@@ -35,7 +35,6 @@ list(APPEND QTGUI_LIBRARIES + gnuradio-blocks + gnuradio-fft + gnuradio-runtime +- ${QWT_LIBRARY_DIRS} + ) + + QT4_WRAP_CPP(qtgui_moc_sources display_qt.h) +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0015-fcd-Update-hidapi-to-latest-HEAD.patch gnuradio-3.7.10.1/debian/patches/0015-fcd-Update-hidapi-to-latest-HEAD.patch --- gnuradio-3.7.10.1/debian/patches/0015-fcd-Update-hidapi-to-latest-HEAD.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0015-fcd-Update-hidapi-to-latest-HEAD.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,1834 @@ +From 67baea5e32de0daef510dfebfa67bf94c0b88f68 Mon Sep 17 00:00:00 2001 +From: Alexandru Csete +Date: Fri, 23 Sep 2016 13:53:25 +0200 +Subject: [PATCH 15/20] fcd: Update hidapi to latest HEAD. + +This contains necessary fixes for Mac OS X. +--- + gr-fcd/lib/hid/hid-libusb.c | 117 +++++++++++-- + gr-fcd/lib/hid/hidapi.h | 32 ++-- + gr-fcd/lib/hid/hidmac.c | 406 +++++++++++++++++++++----------------------- + gr-fcd/lib/hid/hidwin.c | 355 ++++++++++++++++++++++---------------- + 4 files changed, 532 insertions(+), 378 deletions(-) + +diff --git a/gr-fcd/lib/hid/hid-libusb.c b/gr-fcd/lib/hid/hid-libusb.c +index 097f872..3c6d877 100644 +--- a/gr-fcd/lib/hid/hid-libusb.c ++++ b/gr-fcd/lib/hid/hid-libusb.c +@@ -14,7 +14,7 @@ + + At the discretion of the user of this library, + this software may be licensed under the terms of the +- GNU Public License v3, a BSD-Style license, or the ++ GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. +@@ -44,11 +44,74 @@ + #include + + /* GNU / LibUSB */ +-#include "libusb.h" +-#include "iconv.h" ++#include ++#ifndef __ANDROID__ ++#include ++#endif + + #include "hidapi.h" + ++#ifdef __ANDROID__ ++ ++/* Barrier implementation because Android/Bionic don't have pthread_barrier. ++ This implementation came from Brent Priddy and was posted on ++ StackOverflow. It is used with his permission. */ ++typedef int pthread_barrierattr_t; ++typedef struct pthread_barrier { ++ pthread_mutex_t mutex; ++ pthread_cond_t cond; ++ int count; ++ int trip_count; ++} pthread_barrier_t; ++ ++static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) ++{ ++ if(count == 0) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if(pthread_mutex_init(&barrier->mutex, 0) < 0) { ++ return -1; ++ } ++ if(pthread_cond_init(&barrier->cond, 0) < 0) { ++ pthread_mutex_destroy(&barrier->mutex); ++ return -1; ++ } ++ barrier->trip_count = count; ++ barrier->count = 0; ++ ++ return 0; ++} ++ ++static int pthread_barrier_destroy(pthread_barrier_t *barrier) ++{ ++ pthread_cond_destroy(&barrier->cond); ++ pthread_mutex_destroy(&barrier->mutex); ++ return 0; ++} ++ ++static int pthread_barrier_wait(pthread_barrier_t *barrier) ++{ ++ pthread_mutex_lock(&barrier->mutex); ++ ++(barrier->count); ++ if(barrier->count >= barrier->trip_count) ++ { ++ barrier->count = 0; ++ pthread_cond_broadcast(&barrier->cond); ++ pthread_mutex_unlock(&barrier->mutex); ++ return 1; ++ } ++ else ++ { ++ pthread_cond_wait(&barrier->cond, &(barrier->mutex)); ++ pthread_mutex_unlock(&barrier->mutex); ++ return 0; ++ } ++} ++ ++#endif ++ + #ifdef __cplusplus + extern "C" { + #endif +@@ -250,10 +313,10 @@ static int get_usage(uint8_t *report_descriptor, size_t size, + } + #endif /* INVASIVE_GET_USAGE */ + +-#ifdef __FreeBSD__ +-/* The FreeBSD version of libusb doesn't have this funciton. In mainline +- libusb, it's inlined in libusb.h. This function will bear a striking +- resemblence to that one, because there's about one way to code it. ++#if defined(__FreeBSD__) && __FreeBSD__ < 10 ++/* The libusb version included in FreeBSD < 10 doesn't have this function. In ++ mainline libusb, it's inlined in libusb.h. This function will bear a striking ++ resemblance to that one, because there's about one way to code it. + + Note that the data parameter is Unicode in UTF-16LE encoding. + Return value is the number of bytes in data, or LIBUSB_ERROR_*. +@@ -326,8 +389,9 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) + char buf[512]; + int len; + wchar_t *str = NULL; +- wchar_t wbuf[256]; + ++#ifndef __ANDROID__ /* we don't use iconv on Android */ ++ wchar_t wbuf[256]; + /* iconv variables */ + iconv_t ic; + size_t inbytes; +@@ -339,6 +403,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) + char *inptr; + #endif + char *outptr; ++#endif + + /* Determine which language to use. */ + uint16_t lang; +@@ -355,6 +420,25 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) + if (len < 0) + return NULL; + ++#ifdef __ANDROID__ ++ ++ /* Bionic does not have iconv support nor wcsdup() function, so it ++ has to be done manually. The following code will only work for ++ code points that can be represented as a single UTF-16 character, ++ and will incorrectly convert any code points which require more ++ than one UTF-16 character. ++ ++ Skip over the first character (2-bytes). */ ++ len -= 2; ++ str = malloc((len / 2 + 1) * sizeof(wchar_t)); ++ int i; ++ for (i = 0; i < len / 2; i++) { ++ str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); ++ } ++ str[len / 2] = 0x00000000; ++ ++#else ++ + /* buf does not need to be explicitly NULL-terminated because + it is only passed into iconv() which does not need it. */ + +@@ -388,6 +472,8 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) + err: + iconv_close(ic); + ++#endif ++ + return str; + } + +@@ -607,7 +693,7 @@ void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) + } + } + +-hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number) ++hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) + { + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; +@@ -619,7 +705,8 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, wchar + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { +- if (wcscmp(serial_number, cur_dev->serial_number) == 0) { ++ if (cur_dev->serial_number && ++ wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } +@@ -762,7 +849,7 @@ static void *read_thread(void *param) + /* Now that the read thread is stopping, Wake any threads which are + waiting on data (in hid_read_timeout()). Do this under a mutex to + make sure that a thread which is about to go to sleep waiting on +- the condition acutally will go to sleep before the condition is ++ the condition actually will go to sleep before the condition is + signaled. */ + pthread_mutex_lock(&dev->mutex); + pthread_cond_broadcast(&dev->condition); +@@ -790,11 +877,11 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path) + int d = 0; + int good_open = 0; + +- dev = new_hid_device(); +- + if(hid_init() < 0) + return NULL; + ++ dev = new_hid_device(); ++ + libusb_get_device_list(usb_context, &devs); + while ((usb_dev = devs[d++]) != NULL) { + struct libusb_device_descriptor desc; +@@ -871,7 +958,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path) + (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_IN; + +- /* Decide whether to use it for intput or output. */ ++ /* Decide whether to use it for input or output. */ + if (dev->input_endpoint == 0 && + is_interrupt && is_input) { + /* Use this endpoint for INPUT */ +@@ -927,7 +1014,7 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t + + + if (dev->output_endpoint <= 0) { +- /* No interrput out endpoint. Use the Control Endpoint */ ++ /* No interrupt out endpoint. Use the Control Endpoint */ + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, + 0x09/*HID Set_Report*/, +diff --git a/gr-fcd/lib/hid/hidapi.h b/gr-fcd/lib/hid/hidapi.h +index 8e55c84..e5bc2dc 100644 +--- a/gr-fcd/lib/hid/hidapi.h ++++ b/gr-fcd/lib/hid/hidapi.h +@@ -11,7 +11,7 @@ + + At the discretion of the user of this library, + this software may be licensed under the terms of the +- GNU Public License v3, a BSD-Style license, or the ++ GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. +@@ -87,7 +87,7 @@ extern "C" { + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. +- ++ + @ingroup API + + @returns +@@ -112,6 +112,8 @@ extern "C" { + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. ++ If @p vendor_id is set to 0 then any vendor matches. ++ If @p product_id is set to 0 then any product matches. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + +@@ -155,7 +157,7 @@ extern "C" { + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ +- HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number); ++ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + +@@ -207,7 +209,7 @@ extern "C" { + contain the Report number if the device uses numbered reports. + + @ingroup API +- @param dev A device handle returned from hid_open(). ++ @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for +@@ -216,7 +218,8 @@ extern "C" { + + @returns + This function returns the actual number of bytes read and +- -1 on error. ++ -1 on error. If no packet was available to be read within ++ the timeout period, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + +@@ -235,7 +238,8 @@ extern "C" { + + @returns + This function returns the actual number of bytes read and +- -1 on error. ++ -1 on error. If no packet was available to be read and ++ the handle is in non-blocking mode, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + +@@ -289,22 +293,26 @@ extern "C" { + + /** @brief Get a feature report from a HID device. + +- Make sure to set the first byte of @p data[] to the Report +- ID of the report to be read. Make sure to allow space for +- this extra byte in @p data[]. ++ Set the first byte of @p data[] to the Report ID of the ++ report to be read. Make sure to allow space for this ++ extra byte in @p data[]. Upon return, the first byte will ++ still contain the Report ID, and the report data will ++ start in data[1]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the +- Report ID of the report to be read. ++ Report ID of the report to be read, or set it to zero ++ if your device does not use numbered reports. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns +- This function returns the number of bytes read and +- -1 on error. ++ This function returns the number of bytes read plus ++ one for the report ID (which is still in the first ++ byte), or -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + +diff --git a/gr-fcd/lib/hid/hidmac.c b/gr-fcd/lib/hid/hidmac.c +index d8c69a8..e0756a1 100644 +--- a/gr-fcd/lib/hid/hidmac.c ++++ b/gr-fcd/lib/hid/hidmac.c +@@ -11,7 +11,7 @@ + + At the discretion of the user of this library, + this software may be licensed under the terms of the +- GNU Public License v3, a BSD-Style license, or the ++ GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. +@@ -24,12 +24,14 @@ + + #include + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + + #include "hidapi.h" + +@@ -118,16 +120,8 @@ struct hid_device_ { + pthread_barrier_t barrier; /* Ensures correct startup sequence */ + pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */ + int shutdown_thread; +- +- hid_device *next; + }; + +-/* Static list of all the devices open. This way when a device gets +- disconnected, its hid_device structure can be marked as disconnected +- from hid_device_removal_callback(). */ +-static hid_device *device_list = NULL; +-static pthread_mutex_t device_list_mutex = PTHREAD_MUTEX_INITIALIZER; +- + static hid_device *new_hid_device(void) + { + hid_device *dev = calloc(1, sizeof(hid_device)); +@@ -141,7 +135,6 @@ static hid_device *new_hid_device(void) + dev->input_report_buf = NULL; + dev->input_reports = NULL; + dev->shutdown_thread = 0; +- dev->next = NULL; + + /* Thread objects */ + pthread_mutex_init(&dev->mutex, NULL); +@@ -149,22 +142,6 @@ static hid_device *new_hid_device(void) + pthread_barrier_init(&dev->barrier, NULL, 2); + pthread_barrier_init(&dev->shutdown_barrier, NULL, 2); + +- /* Add the new record to the device_list. */ +- pthread_mutex_lock(&device_list_mutex); +- if (!device_list) +- device_list = dev; +- else { +- hid_device *d = device_list; +- while (d) { +- if (!d->next) { +- d->next = dev; +- break; +- } +- d = d->next; +- } +- } +- pthread_mutex_unlock(&device_list_mutex); +- + return dev; + } + +@@ -197,29 +174,11 @@ static void free_hid_device(hid_device *dev) + pthread_cond_destroy(&dev->condition); + pthread_mutex_destroy(&dev->mutex); + +- /* Remove it from the device list. */ +- pthread_mutex_lock(&device_list_mutex); +- hid_device *d = device_list; +- if (d == dev) { +- device_list = d->next; +- } +- else { +- while (d) { +- if (d->next == dev) { +- d->next = d->next->next; +- break; +- } +- +- d = d->next; +- } +- } +- pthread_mutex_unlock(&device_list_mutex); +- + /* Free the structure itself. */ + free(dev); + } + +-static IOHIDManagerRef hid_mgr = 0x0; ++static IOHIDManagerRef hid_mgr = 0x0; + + + #if 0 +@@ -255,7 +214,6 @@ static unsigned short get_product_id(IOHIDDeviceRef device) + return get_int_property(device, CFSTR(kIOHIDProductIDKey)); + } + +- + static int32_t get_max_report_length(IOHIDDeviceRef device) + { + return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey)); +@@ -263,59 +221,46 @@ static int32_t get_max_report_length(IOHIDDeviceRef device) + + static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len) + { +- CFStringRef str = IOHIDDeviceGetProperty(device, prop); ++ CFStringRef str; + +- buf[0] = 0x0000; +- +- if (str) { +- CFRange range; +- range.location = 0; +- range.length = len; +- CFIndex used_buf_len; +- CFStringGetBytes(str, +- range, +- kCFStringEncodingUTF32LE, +- (char)'?', +- FALSE, +- (UInt8*)buf, +- len, +- &used_buf_len); +- buf[len-1] = 0x00000000; +- return used_buf_len; +- } +- else ++ if (!len) + return 0; + +-} +- +-static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, char *buf, size_t len) +-{ +- CFStringRef str = IOHIDDeviceGetProperty(device, prop); ++ str = IOHIDDeviceGetProperty(device, prop); + +- buf[0] = 0x0000; ++ buf[0] = 0; + + if (str) { ++ CFIndex str_len = CFStringGetLength(str); + CFRange range; +- range.location = 0; +- range.length = len; + CFIndex used_buf_len; +- CFStringGetBytes(str, ++ CFIndex chars_copied; ++ ++ len --; ++ ++ range.location = 0; ++ range.length = ((size_t)str_len > len)? len: (size_t)str_len; ++ chars_copied = CFStringGetBytes(str, + range, +- kCFStringEncodingUTF8, ++ kCFStringEncodingUTF32LE, + (char)'?', + FALSE, + (UInt8*)buf, +- len, ++ len * sizeof(wchar_t), + &used_buf_len); +- buf[len-1] = 0x00000000; +- return used_buf_len; ++ ++ if (chars_copied == len) ++ buf[len] = 0; /* len is decremented above */ ++ else ++ buf[chars_copied] = 0; ++ ++ return 0; + } + else +- return 0; ++ return -1; + + } + +- + static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len) + { + return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len); +@@ -342,53 +287,87 @@ static wchar_t *dup_wcs(const wchar_t *s) + return ret; + } + +- +-static int make_path(IOHIDDeviceRef device, char *buf, size_t len) ++/* hidapi_IOHIDDeviceGetService() ++ * ++ * Return the io_service_t corresponding to a given IOHIDDeviceRef, either by: ++ * - on OS X 10.6 and above, calling IOHIDDeviceGetService() ++ * - on OS X 10.5, extract it from the IOHIDDevice struct ++ */ ++static io_service_t hidapi_IOHIDDeviceGetService(IOHIDDeviceRef device) + { +- int res; +- unsigned short vid, pid; +- char transport[32]; +- +- buf[0] = '\0'; +- +- res = get_string_property_utf8( +- device, CFSTR(kIOHIDTransportKey), +- transport, sizeof(transport)); +- +- if (!res) +- return -1; +- +- vid = get_vendor_id(device); +- pid = get_product_id(device); +- +- res = snprintf(buf, len, "%s_%04hx_%04hx_%p", +- transport, vid, pid, device); ++ static void *iokit_framework = NULL; ++ static io_service_t (*dynamic_IOHIDDeviceGetService)(IOHIDDeviceRef device) = NULL; ++ ++ /* Use dlopen()/dlsym() to get a pointer to IOHIDDeviceGetService() if it exists. ++ * If any of these steps fail, dynamic_IOHIDDeviceGetService will be left NULL ++ * and the fallback method will be used. ++ */ ++ if (iokit_framework == NULL) { ++ iokit_framework = dlopen("/System/Library/IOKit.framework/IOKit", RTLD_LAZY); ++ ++ if (iokit_framework != NULL) ++ dynamic_IOHIDDeviceGetService = dlsym(iokit_framework, "IOHIDDeviceGetService"); ++ } + ++ if (dynamic_IOHIDDeviceGetService != NULL) { ++ /* Running on OS X 10.6 and above: IOHIDDeviceGetService() exists */ ++ return dynamic_IOHIDDeviceGetService(device); ++ } ++ else ++ { ++ /* Running on OS X 10.5: IOHIDDeviceGetService() doesn't exist. ++ * ++ * Be naughty and pull the service out of the IOHIDDevice. ++ * IOHIDDevice is an opaque struct not exposed to applications, but its ++ * layout is stable through all available versions of OS X. ++ * Tested and working on OS X 10.5.8 i386, x86_64, and ppc. ++ */ ++ struct IOHIDDevice_internal { ++ /* The first field of the IOHIDDevice struct is a ++ * CFRuntimeBase (which is a private CF struct). ++ * ++ * a, b, and c are the 3 fields that make up a CFRuntimeBase. ++ * See http://opensource.apple.com/source/CF/CF-476.18/CFRuntime.h ++ * ++ * The second field of the IOHIDDevice is the io_service_t we're looking for. ++ */ ++ uintptr_t a; ++ uint8_t b[4]; ++#if __LP64__ ++ uint32_t c; ++#endif ++ io_service_t service; ++ }; ++ struct IOHIDDevice_internal *tmp = (struct IOHIDDevice_internal *)device; + +- buf[len-1] = '\0'; +- return res+1; ++ return tmp->service; ++ } + } + ++/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */ + static int init_hid_manager(void) + { +- IOReturn res; +- + /* Initialize all the HID Manager Objects */ + hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); +- IOHIDManagerSetDeviceMatching(hid_mgr, NULL); +- IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); +- res = IOHIDManagerOpen(hid_mgr, kIOHIDOptionsTypeNone); +- return (res == kIOReturnSuccess)? 0: -1; ++ if (hid_mgr) { ++ IOHIDManagerSetDeviceMatching(hid_mgr, NULL); ++ IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); ++ return 0; ++ } ++ ++ return -1; + } + ++/* Initialize the IOHIDManager if necessary. This is the public function, and ++ it is safe to call this function repeatedly. Return 0 for success and -1 ++ for failure. */ + int HID_API_EXPORT hid_init(void) + { + if (!hid_mgr) { +- if (init_hid_manager() < 0) { +- hid_exit(); +- return -1; +- } ++ return init_hid_manager(); + } ++ ++ /* Already initialized. */ + return 0; + } + +@@ -404,19 +383,29 @@ int HID_API_EXPORT hid_exit(void) + return 0; + } + ++static void process_pending_events(void) { ++ SInt32 res; ++ do { ++ res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE); ++ } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut); ++} ++ + struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) + { +- struct hid_device_info *root = NULL; // return object ++ struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + CFIndex num_devices; + int i; + +- setlocale(LC_ALL,""); +- + /* Set up the HID Manager if it hasn't been done */ +- hid_init(); ++ if (hid_init() < 0) ++ return NULL; ++ ++ /* give the IOHIDManager a chance to update itself */ ++ process_pending_events(); + + /* Get a list of the Devices */ ++ IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); + + /* Convert the list into a C array so we can iterate easily. */ +@@ -430,7 +419,6 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, + unsigned short dev_pid; + #define BUF_LEN 256 + wchar_t buf[BUF_LEN]; +- char cbuf[BUF_LEN]; + + IOHIDDeviceRef dev = device_array[i]; + +@@ -441,12 +429,14 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, + dev_pid = get_product_id(dev); + + /* Check the VID/PID against the arguments */ +- if ((vendor_id == 0x0 && product_id == 0x0) || +- (vendor_id == dev_vid && product_id == dev_pid)) { ++ if ((vendor_id == 0x0 || vendor_id == dev_vid) && ++ (product_id == 0x0 || product_id == dev_pid)) { + struct hid_device_info *tmp; +- size_t len; ++ io_object_t iokit_dev; ++ kern_return_t res; ++ io_string_t path; + +- /* VID/PID match. Create the record. */ ++ /* VID/PID match. Create the record. */ + tmp = malloc(sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; +@@ -456,14 +446,20 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, + } + cur_dev = tmp; + +- // Get the Usage Page and Usage for this device. ++ /* Get the Usage Page and Usage for this device. */ + cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey)); + cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey)); + + /* Fill out the record */ + cur_dev->next = NULL; +- len = make_path(dev, cbuf, sizeof(cbuf)); +- cur_dev->path = strdup(cbuf); ++ ++ /* Fill in the path (IOService plane) */ ++ iokit_dev = hidapi_IOHIDDeviceGetService(dev); ++ res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path); ++ if (res == KERN_SUCCESS) ++ cur_dev->path = strdup(path); ++ else ++ cur_dev->path = strdup(""); + + /* Serial Number */ + get_serial_number(dev, buf, BUF_LEN); +@@ -508,7 +504,7 @@ void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) + } + } + +-hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number) ++hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) + { + /* This function is identical to the Linux version. Platform independent. */ + struct hid_device_info *devs, *cur_dev; +@@ -545,20 +541,13 @@ hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short pr + } + + static void hid_device_removal_callback(void *context, IOReturn result, +- void *sender, IOHIDDeviceRef dev_ref) ++ void *sender) + { + /* Stop the Run Loop for this device. */ +- pthread_mutex_lock(&device_list_mutex); +- hid_device *d = device_list; +- while (d) { +- if (d->device_handle == dev_ref) { +- d->disconnected = 1; +- CFRunLoopStop(d->run_loop); +- } ++ hid_device *d = context; + +- d = d->next; +- } +- pthread_mutex_unlock(&device_list_mutex); ++ d->disconnected = 1; ++ CFRunLoopStop(d->run_loop); + } + + /* The Run Loop calls this function for each input report received. +@@ -612,17 +601,18 @@ static void hid_report_callback(void *context, IOReturn result, void *sender, + + } + +-/* This gets called when the read_thred's run loop gets signaled by ++/* This gets called when the read_thread's run loop gets signaled by + hid_close(), and serves to stop the read_thread's run loop. */ + static void perform_signal_callback(void *context) + { + hid_device *dev = context; +- CFRunLoopStop(dev->run_loop); //TODO: CFRunLoopGetCurrent() ++ CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/ + } + + static void *read_thread(void *param) + { + hid_device *dev = param; ++ SInt32 code; + + /* Move the device's run loop to this thread. */ + IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); +@@ -646,7 +636,6 @@ static void *read_thread(void *param) + + /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input + reports into the hid_report_callback(). */ +- SInt32 code; + while (!dev->shutdown_thread && !dev->disconnected) { + code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE); + /* Return if the device has been disconnected */ +@@ -670,19 +659,12 @@ static void *read_thread(void *param) + /* Now that the read thread is stopping, Wake any threads which are + waiting on data (in hid_read_timeout()). Do this under a mutex to + make sure that a thread which is about to go to sleep waiting on +- the condition acutally will go to sleep before the condition is ++ the condition actually will go to sleep before the condition is + signaled. */ + pthread_mutex_lock(&dev->mutex); + pthread_cond_broadcast(&dev->condition); + pthread_mutex_unlock(&dev->mutex); + +- /* Close the OS handle to the device, but only if it's not +- been unplugged. If it's been unplugged, then calling +- IOHIDDeviceClose() will crash. */ +- if (!dev->disconnected) { +- IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone); +- } +- + /* Wait here until hid_close() is called and makes it past + the call to CFRunLoopWakeUp(). This thread still needs to + be valid when that function is called on the other thread. */ +@@ -691,71 +673,77 @@ static void *read_thread(void *param) + return NULL; + } + ++/* hid_open_path() ++ * ++ * path must be a valid path to an IOHIDDevice in the IOService plane ++ * Example: "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/EHC1@1D,7/AppleUSBEHCI/PLAYSTATION(R)3 Controller@fd120000/IOUSBInterface@0/IOUSBHIDDriver" ++ */ + hid_device * HID_API_EXPORT hid_open_path(const char *path) + { +- int i; + hid_device *dev = NULL; +- CFIndex num_devices; ++ io_registry_entry_t entry = MACH_PORT_NULL; + + dev = new_hid_device(); + + /* Set up the HID Manager if it hasn't been done */ +- hid_init(); ++ if (hid_init() < 0) ++ return NULL; ++ ++ /* Get the IORegistry entry for the given path */ ++ entry = IORegistryEntryFromPath(kIOMasterPortDefault, path); ++ if (entry == MACH_PORT_NULL) { ++ /* Path wasn't valid (maybe device was removed?) */ ++ goto return_error; ++ } + +- CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); ++ /* Create an IOHIDDevice for the entry */ ++ dev->device_handle = IOHIDDeviceCreate(kCFAllocatorDefault, entry); ++ if (dev->device_handle == NULL) { ++ /* Error creating the HID device */ ++ goto return_error; ++ } + +- num_devices = CFSetGetCount(device_set); +- IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); +- CFSetGetValues(device_set, (const void **) device_array); +- for (i = 0; i < num_devices; i++) { +- char cbuf[BUF_LEN]; +- size_t len; +- IOHIDDeviceRef os_dev = device_array[i]; +- +- len = make_path(os_dev, cbuf, sizeof(cbuf)); +- if (!strcmp(cbuf, path)) { +- // Matched Paths. Open this Device. +- IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone); +- if (ret == kIOReturnSuccess) { +- char str[32]; +- +- free(device_array); +- CFRelease(device_set); +- dev->device_handle = os_dev; +- +- /* Create the buffers for receiving data */ +- dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev); +- dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t)); +- +- /* Create the Run Loop Mode for this device. +- printing the reference seems to work. */ +- sprintf(str, "HIDAPI_%p", os_dev); +- dev->run_loop_mode = +- CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); +- +- /* Attach the device to a Run Loop */ +- IOHIDDeviceRegisterInputReportCallback( +- os_dev, dev->input_report_buf, dev->max_input_report_len, +- &hid_report_callback, dev); +- IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, hid_device_removal_callback, NULL); +- +- /* Start the read thread */ +- pthread_create(&dev->thread, NULL, read_thread, dev); +- +- /* Wait here for the read thread to be initialized. */ +- pthread_barrier_wait(&dev->barrier); +- +- return dev; +- } +- else { +- goto return_error; +- } +- } ++ /* Open the IOHIDDevice */ ++ IOReturn ret = IOHIDDeviceOpen(dev->device_handle, kIOHIDOptionsTypeSeizeDevice); ++ if (ret == kIOReturnSuccess) { ++ char str[32]; ++ ++ /* Create the buffers for receiving data */ ++ dev->max_input_report_len = (CFIndex) get_max_report_length(dev->device_handle); ++ dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t)); ++ ++ /* Create the Run Loop Mode for this device. ++ printing the reference seems to work. */ ++ sprintf(str, "HIDAPI_%p", dev->device_handle); ++ dev->run_loop_mode = ++ CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); ++ ++ /* Attach the device to a Run Loop */ ++ IOHIDDeviceRegisterInputReportCallback( ++ dev->device_handle, dev->input_report_buf, dev->max_input_report_len, ++ &hid_report_callback, dev); ++ IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev); ++ ++ /* Start the read thread */ ++ pthread_create(&dev->thread, NULL, read_thread, dev); ++ ++ /* Wait here for the read thread to be initialized. */ ++ pthread_barrier_wait(&dev->barrier); ++ ++ IOObjectRelease(entry); ++ return dev; ++ } ++ else { ++ goto return_error; + } + + return_error: +- free(device_array); +- CFRelease(device_set); ++ if (dev->device_handle != NULL) ++ CFRelease(dev->device_handle); ++ ++ if (entry != MACH_PORT_NULL) ++ IOObjectRelease(entry); ++ + free_hid_device(dev); + return NULL; + } +@@ -767,8 +755,8 @@ static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char + IOReturn res; + + /* Return if the device has been disconnected. */ +- if (dev->disconnected) +- return -1; ++ if (dev->disconnected) ++ return -1; + + if (data[0] == 0x0) { + /* Not using numbered Reports. +@@ -981,7 +969,7 @@ void HID_API_EXPORT hid_close(hid_device *dev) + IOHIDDeviceRegisterInputReportCallback( + dev->device_handle, dev->input_report_buf, dev->max_input_report_len, + NULL, dev); +- IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, NULL, dev); ++ IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, dev); + IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode); + IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode); + } +@@ -1003,7 +991,7 @@ void HID_API_EXPORT hid_close(hid_device *dev) + been unplugged. If it's been unplugged, then calling + IOHIDDeviceClose() will crash. */ + if (!dev->disconnected) { +- IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone); ++ IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeSeizeDevice); + } + + /* Clear out the queue of received reports. */ +@@ -1012,6 +1000,7 @@ void HID_API_EXPORT hid_close(hid_device *dev) + return_data(dev, NULL, 0); + } + pthread_mutex_unlock(&dev->mutex); ++ CFRelease(dev->device_handle); + + free_hid_device(dev); + } +@@ -1033,7 +1022,7 @@ int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *s + + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) + { +- // TODO: ++ /* TODO: */ + + return 0; + } +@@ -1041,7 +1030,7 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index + + HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) + { +- // TODO: ++ /* TODO: */ + + return NULL; + } +@@ -1051,6 +1040,7 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) + + + ++ + #if 0 + static int32_t get_location_id(IOHIDDeviceRef device) + { +@@ -1096,8 +1086,6 @@ int main(void) + IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); + CFSetGetValues(device_set, (const void **) device_array); + +- setlocale(LC_ALL, ""); +- + for (i = 0; i < num_devices; i++) { + IOHIDDeviceRef dev = device_array[i]; + printf("Device: %p\n", dev); +diff --git a/gr-fcd/lib/hid/hidwin.c b/gr-fcd/lib/hid/hidwin.c +index 5d34aad..86810d7 100644 +--- a/gr-fcd/lib/hid/hidwin.c ++++ b/gr-fcd/lib/hid/hidwin.c +@@ -8,10 +8,10 @@ + 8/22/2009 + + Copyright 2009, All Rights Reserved. +- ++ + At the discretion of the user of this library, + this software may be licensed under the terms of the +- GNU Public License v3, a BSD-Style license, or the ++ GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. +@@ -36,7 +36,11 @@ typedef LONG NTSTATUS; + #define _wcsdup wcsdup + #endif + +-//#define HIDAPI_USE_DDK ++/* The maximum number of characters that can be passed into the ++ HidD_Get*String() functions without it failing.*/ ++#define MAX_STRING_WCHARS 0xFFF ++ ++/*#define HIDAPI_USE_DDK*/ + + #ifdef __cplusplus + extern "C" { +@@ -47,13 +51,13 @@ extern "C" { + #include + #endif + +- // Copied from inc/ddk/hidclass.h, part of the Windows DDK. ++ /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */ + #define HID_OUT_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) + + #ifdef __cplusplus +-} // extern "C" ++} /* extern "C" */ + #endif + + #include +@@ -62,8 +66,11 @@ extern "C" { + + #include "hidapi.h" + ++#undef MIN ++#define MIN(x,y) ((x) < (y)? (x): (y)) ++ + #ifdef _MSC_VER +- // Thanks Microsoft, but I know how to use strncpy(). ++ /* Thanks Microsoft, but I know how to use strncpy(). */ + #pragma warning(disable:4996) + #endif + +@@ -72,10 +79,10 @@ extern "C" { + #endif + + #ifndef HIDAPI_USE_DDK +- // Since we're not building with the DDK, and the HID header +- // files aren't part of the SDK, we have to define all this +- // stuff here. In lookup_functions(), the function pointers +- // defined below are set. ++ /* Since we're not building with the DDK, and the HID header ++ files aren't part of the SDK, we have to define all this ++ stuff here. In lookup_functions(), the function pointers ++ defined below are set. */ + typedef struct _HIDD_ATTRIBUTES{ + ULONG Size; + USHORT VendorID; +@@ -93,8 +100,8 @@ extern "C" { + USHORT Reserved[17]; + USHORT fields_not_used_by_hidapi[10]; + } HIDP_CAPS, *PHIDP_CAPS; +- typedef char* HIDP_PREPARSED_DATA; +- #define HIDP_STATUS_SUCCESS 0x0 ++ typedef void* PHIDP_PREPARSED_DATA; ++ #define HIDP_STATUS_SUCCESS 0x110000 + + typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib); + typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len); +@@ -103,9 +110,10 @@ extern "C" { + typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len); +- typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, HIDP_PREPARSED_DATA **preparsed_data); +- typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(HIDP_PREPARSED_DATA *preparsed_data); +- typedef BOOLEAN (__stdcall *HidP_GetCaps_)(HIDP_PREPARSED_DATA *preparsed_data, HIDP_CAPS *caps); ++ typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data); ++ typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data); ++ typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps); ++ typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers); + + static HidD_GetAttributes_ HidD_GetAttributes; + static HidD_GetSerialNumberString_ HidD_GetSerialNumberString; +@@ -117,14 +125,16 @@ extern "C" { + static HidD_GetPreparsedData_ HidD_GetPreparsedData; + static HidD_FreePreparsedData_ HidD_FreePreparsedData; + static HidP_GetCaps_ HidP_GetCaps; ++ static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers; + + static HMODULE lib_handle = NULL; + static BOOLEAN initialized = FALSE; +-#endif // HIDAPI_USE_DDK ++#endif /* HIDAPI_USE_DDK */ + + struct hid_device_ { + HANDLE device_handle; + BOOL blocking; ++ USHORT output_report_length; + size_t input_report_length; + void *last_error_str; + DWORD last_error_num; +@@ -138,17 +148,26 @@ static hid_device *new_hid_device() + hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); + dev->device_handle = INVALID_HANDLE_VALUE; + dev->blocking = TRUE; ++ dev->output_report_length = 0; + dev->input_report_length = 0; + dev->last_error_str = NULL; + dev->last_error_num = 0; + dev->read_pending = FALSE; + dev->read_buf = NULL; + memset(&dev->ol, 0, sizeof(dev->ol)); +- dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL); ++ dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); + + return dev; + } + ++static void free_hid_device(hid_device *dev) ++{ ++ CloseHandle(dev->ol.hEvent); ++ CloseHandle(dev->device_handle); ++ LocalFree(dev->last_error_str); ++ free(dev->read_buf); ++ free(dev); ++} + + static void register_error(hid_device *device, const char *op) + { +@@ -160,11 +179,11 @@ static void register_error(hid_device *device, const char *op) + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), +- (LPWSTR)&msg, 0/*sz*/, ++ (LPVOID)&msg, 0/*sz*/, + NULL); +- +- // Get rid of the CR and LF that FormatMessage() sticks at the +- // end of the message. Thanks Microsoft! ++ ++ /* Get rid of the CR and LF that FormatMessage() sticks at the ++ end of the message. Thanks Microsoft! */ + ptr = msg; + while (*ptr) { + if (*ptr == '\r') { +@@ -174,8 +193,8 @@ static void register_error(hid_device *device, const char *op) + ptr++; + } + +- // Store the message off in the Device entry so that +- // the hid_error() function can pick it up. ++ /* Store the message off in the Device entry so that ++ the hid_error() function can pick it up. */ + LocalFree(device->last_error_str); + device->last_error_str = msg; + } +@@ -196,6 +215,7 @@ static int lookup_functions() + RESOLVE(HidD_GetPreparsedData); + RESOLVE(HidD_FreePreparsedData); + RESOLVE(HidP_GetCaps); ++ RESOLVE(HidD_SetNumInputBuffers); + #undef RESOLVE + } + else +@@ -205,34 +225,20 @@ static int lookup_functions() + } + #endif + +-static HANDLE open_device(const char *path) ++static HANDLE open_device(const char *path, BOOL enumerate) + { + HANDLE handle; ++ DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ); ++ DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + +- /* First, try to open with sharing mode turned off. This will make it so +- that a HID device can only be opened once. This is to be consistent +- with the behavior on the other platforms. */ + handle = CreateFileA(path, +- GENERIC_WRITE |GENERIC_READ, +- 0, /*share mode*/ ++ desired_access, ++ share_mode, + NULL, + OPEN_EXISTING, +- FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL, ++ FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/ + 0); + +- if (handle == INVALID_HANDLE_VALUE) { +- /* Couldn't open the device. Some devices must be opened +- with sharing enabled (even though they are only opened once), +- so try it here. */ +- handle = CreateFileA(path, +- GENERIC_WRITE |GENERIC_READ, +- FILE_SHARE_READ|FILE_SHARE_WRITE, /*share mode*/ +- NULL, +- OPEN_EXISTING, +- FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL, +- 0); +- } +- + return handle; + } + +@@ -264,29 +270,31 @@ int HID_API_EXPORT hid_exit(void) + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) + { + BOOL res; +- struct hid_device_info *root = NULL; // return object ++ struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + +- // Windows objects for interacting with the driver. ++ /* Windows objects for interacting with the driver. */ + GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; + SP_DEVINFO_DATA devinfo_data; + SP_DEVICE_INTERFACE_DATA device_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; + HDEVINFO device_info_set = INVALID_HANDLE_VALUE; + int device_index = 0; ++ int i; + + if (hid_init() < 0) + return NULL; + +- // Initialize the Windows objects. ++ /* Initialize the Windows objects. */ ++ memset(&devinfo_data, 0x0, sizeof(devinfo_data)); + devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); + device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + +- // Get information for all the devices belonging to the HID class. ++ /* Get information for all the devices belonging to the HID class. */ + device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); +- +- // Iterate over each device in the HID class, looking for the right one. +- ++ ++ /* Iterate over each device in the HID class, looking for the right one. */ ++ + for (;;) { + HANDLE write_handle = INVALID_HANDLE_VALUE; + DWORD required_size = 0; +@@ -297,16 +305,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor + &InterfaceClassGuid, + device_index, + &device_interface_data); +- ++ + if (!res) { +- // A return of FALSE from this function means that +- // there are no more devices. ++ /* A return of FALSE from this function means that ++ there are no more devices. */ + break; + } + +- // Call with 0-sized detail size, and let the function +- // tell us how long the detail struct needs to be. The +- // size is put in &required_size. ++ /* Call with 0-sized detail size, and let the function ++ tell us how long the detail struct needs to be. The ++ size is put in &required_size. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + NULL, +@@ -314,13 +322,13 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor + &required_size, + NULL); + +- // Allocate a long enough structure for device_interface_detail_data. ++ /* Allocate a long enough structure for device_interface_detail_data. */ + device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); + device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + +- // Get the detailed data for this device. The detail data gives us +- // the device path for this device, which is then passed into +- // CreateFile() to get a handle to the device. ++ /* Get the detailed data for this device. The detail data gives us ++ the device path for this device, which is then passed into ++ CreateFile() to get a handle to the device. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + device_interface_detail_data, +@@ -329,42 +337,67 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor + NULL); + + if (!res) { +- //register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); +- // Continue to the next device. ++ /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); ++ Continue to the next device. */ + goto cont; + } + ++ /* Make sure this device is of Setup Class "HIDClass" and has a ++ driver bound to it. */ ++ for (i = 0; ; i++) { ++ char driver_name[256]; ++ ++ /* Populate devinfo_data. This function will return failure ++ when there are no more interfaces left. */ ++ res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); ++ if (!res) ++ goto cont; ++ ++ res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, ++ SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); ++ if (!res) ++ goto cont; ++ ++ if (strcmp(driver_name, "HIDClass") == 0) { ++ /* See if there's a driver bound. */ ++ res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, ++ SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); ++ if (res) ++ break; ++ } ++ } ++ + //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); + +- // Open a handle to the device +- write_handle = open_device(device_interface_detail_data->DevicePath); ++ /* Open a handle to the device */ ++ write_handle = open_device(device_interface_detail_data->DevicePath, TRUE); + +- // Check validity of write_handle. ++ /* Check validity of write_handle. */ + if (write_handle == INVALID_HANDLE_VALUE) { +- // Unable to open the device. ++ /* Unable to open the device. */ + //register_error(dev, "CreateFile"); + goto cont_close; +- } ++ } + + +- // Get the Vendor ID and Product ID for this device. ++ /* Get the Vendor ID and Product ID for this device. */ + attrib.Size = sizeof(HIDD_ATTRIBUTES); + HidD_GetAttributes(write_handle, &attrib); + //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + +- // Check the VID/PID to see if we should add this +- // device to the enumeration list. +- if ((vendor_id == 0x0 && product_id == 0x0) || +- (attrib.VendorID == vendor_id && attrib.ProductID == product_id)) { ++ /* Check the VID/PID to see if we should add this ++ device to the enumeration list. */ ++ if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && ++ (product_id == 0x0 || attrib.ProductID == product_id)) { + + #define WSTR_LEN 512 + const char *str; + struct hid_device_info *tmp; +- HIDP_PREPARSED_DATA *pp_data = NULL; ++ PHIDP_PREPARSED_DATA pp_data = NULL; + HIDP_CAPS caps; + BOOLEAN res; + NTSTATUS nt_res; +- wchar_t wstr[WSTR_LEN]; // TODO: Determine Size ++ wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ + size_t len; + + /* VID/PID match. Create the record. */ +@@ -377,7 +410,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor + } + cur_dev = tmp; + +- // Get the Usage Page and Usage for this device. ++ /* Get the Usage Page and Usage for this device. */ + res = HidD_GetPreparsedData(write_handle, &pp_data); + if (res) { + nt_res = HidP_GetCaps(pp_data, &caps); +@@ -388,7 +421,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor + + HidD_FreePreparsedData(pp_data); + } +- ++ + /* Fill out the record */ + cur_dev->next = NULL; + str = device_interface_detail_data->DevicePath; +@@ -452,14 +485,14 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor + cont_close: + CloseHandle(write_handle); + cont: +- // We no longer need the detail data. It can be freed ++ /* We no longer need the detail data. It can be freed */ + free(device_interface_detail_data); + + device_index++; + + } + +- // Close the device information handle. ++ /* Close the device information handle. */ + SetupDiDestroyDeviceInfoList(device_info_set); + + return root; +@@ -468,7 +501,7 @@ cont: + + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) + { +- // TODO: Merge this with the Linux version. This function is platform-independent. ++ /* TODO: Merge this with the Linux version. This function is platform-independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; +@@ -482,13 +515,13 @@ void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *d + } + + +-HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number) ++HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) + { +- // TODO: Merge this functions with the Linux version. This function should be platform independent. ++ /* TODO: Merge this functions with the Linux version. This function should be platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; +- ++ + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { +@@ -514,7 +547,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi + } + + hid_free_enumeration(devs); +- ++ + return handle; + } + +@@ -522,7 +555,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) + { + hid_device *dev; + HIDP_CAPS caps; +- HIDP_PREPARSED_DATA *pp_data = NULL; ++ PHIDP_PREPARSED_DATA pp_data = NULL; + BOOLEAN res; + NTSTATUS nt_res; + +@@ -532,17 +565,24 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) + + dev = new_hid_device(); + +- // Open a handle to the device +- dev->device_handle = open_device(path); ++ /* Open a handle to the device */ ++ dev->device_handle = open_device(path, FALSE); + +- // Check validity of write_handle. ++ /* Check validity of write_handle. */ + if (dev->device_handle == INVALID_HANDLE_VALUE) { +- // Unable to open the device. ++ /* Unable to open the device. */ + register_error(dev, "CreateFile"); + goto err; + } + +- // Get the Input Report length for the device. ++ /* Set the Input Report buffer size to 64 reports. */ ++ res = HidD_SetNumInputBuffers(dev->device_handle, 64); ++ if (!res) { ++ register_error(dev, "HidD_SetNumInputBuffers"); ++ goto err; ++ } ++ ++ /* Get the Input Report length for the device. */ + res = HidD_GetPreparsedData(dev->device_handle, &pp_data); + if (!res) { + register_error(dev, "HidD_GetPreparsedData"); +@@ -550,9 +590,10 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) + } + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res != HIDP_STATUS_SUCCESS) { +- register_error(dev, "HidP_GetCaps"); ++ register_error(dev, "HidP_GetCaps"); + goto err_pp_data; + } ++ dev->output_report_length = caps.OutputReportByteLength; + dev->input_report_length = caps.InputReportByteLength; + HidD_FreePreparsedData(pp_data); + +@@ -562,9 +603,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) + + err_pp_data: + HidD_FreePreparsedData(pp_data); +-err: +- CloseHandle(dev->device_handle); +- free(dev); ++err: ++ free_hid_device(dev); + return NULL; + } + +@@ -574,27 +614,52 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char * + BOOL res; + + OVERLAPPED ol; ++ unsigned char *buf; + memset(&ol, 0, sizeof(ol)); + +- res = WriteFile(dev->device_handle, data, length, NULL, &ol); ++ /* Make sure the right number of bytes are passed to WriteFile. Windows ++ expects the number of bytes which are in the _longest_ report (plus ++ one for the report number) bytes even if the data is a report ++ which is shorter than that. Windows gives us this value in ++ caps.OutputReportByteLength. If a user passes in fewer bytes than this, ++ create a temporary buffer which is the proper size. */ ++ if (length >= dev->output_report_length) { ++ /* The user passed the right number of bytes. Use the buffer as-is. */ ++ buf = (unsigned char *) data; ++ } else { ++ /* Create a temporary buffer and copy the user's data ++ into it, padding the rest with zeros. */ ++ buf = (unsigned char *) malloc(dev->output_report_length); ++ memcpy(buf, data, length); ++ memset(buf + length, 0, dev->output_report_length - length); ++ length = dev->output_report_length; ++ } + ++ res = WriteFile(dev->device_handle, buf, length, NULL, &ol); ++ + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { +- // WriteFile() failed. Return error. ++ /* WriteFile() failed. Return error. */ + register_error(dev, "WriteFile"); +- return -1; ++ bytes_written = -1; ++ goto end_of_function; + } + } + +- // Wait here until the write is done. This makes +- // hid_write() synchronous. ++ /* Wait here until the write is done. This makes ++ hid_write() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/); + if (!res) { +- // The Write operation failed. ++ /* The Write operation failed. */ + register_error(dev, "WriteFile"); +- return -1; ++ bytes_written = -1; ++ goto end_of_function; + } + ++end_of_function: ++ if (buf != data) ++ free(buf); ++ + return bytes_written; + } + +@@ -602,21 +667,23 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char * + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) + { + DWORD bytes_read = 0; ++ size_t copy_len = 0; + BOOL res; + +- // Copy the handle for convenience. ++ /* Copy the handle for convenience. */ + HANDLE ev = dev->ol.hEvent; + + if (!dev->read_pending) { +- // Start an Overlapped I/O read. ++ /* Start an Overlapped I/O read. */ + dev->read_pending = TRUE; ++ memset(dev->read_buf, 0, dev->input_report_length); + ResetEvent(ev); + res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol); +- ++ + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { +- // ReadFile() has failed. +- // Clean up and return error. ++ /* ReadFile() has failed. ++ Clean up and return error. */ + CancelIo(dev->device_handle); + dev->read_pending = FALSE; + goto end_of_function; +@@ -625,21 +692,21 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char + } + + if (milliseconds >= 0) { +- // See if there is any data yet. ++ /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds); + if (res != WAIT_OBJECT_0) { +- // There was no data this time. Return zero bytes available, +- // but leave the Overlapped I/O running. ++ /* There was no data this time. Return zero bytes available, ++ but leave the Overlapped I/O running. */ + return 0; + } + } + +- // Either WaitForSingleObject() told us that ReadFile has completed, or +- // we are in non-blocking mode. Get the number of bytes read. The actual +- // data has been copied to the data[] array which was passed to ReadFile(). ++ /* Either WaitForSingleObject() told us that ReadFile has completed, or ++ we are in non-blocking mode. Get the number of bytes read. The actual ++ data has been copied to the data[] array which was passed to ReadFile(). */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); +- +- // Set pending back to false, even if GetOverlappedResult() returned error. ++ ++ /* Set pending back to false, even if GetOverlappedResult() returned error. */ + dev->read_pending = FALSE; + + if (res && bytes_read > 0) { +@@ -649,21 +716,23 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char + work like the other platforms, and to make it work more like the + HID spec, we'll skip over this byte. */ + bytes_read--; +- memcpy(data, dev->read_buf+1, length); ++ copy_len = length > bytes_read ? bytes_read : length; ++ memcpy(data, dev->read_buf+1, copy_len); + } + else { + /* Copy the whole buffer, report number and all. */ +- memcpy(data, dev->read_buf, length); ++ copy_len = length > bytes_read ? bytes_read : length; ++ memcpy(data, dev->read_buf, copy_len); + } + } +- ++ + end_of_function: + if (!res) { + register_error(dev, "GetOverlappedResult"); + return -1; + } +- +- return bytes_read; ++ ++ return copy_len; + } + + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length) +@@ -713,20 +782,26 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { +- // DeviceIoControl() failed. Return error. ++ /* DeviceIoControl() failed. Return error. */ + register_error(dev, "Send Feature Report DeviceIoControl"); + return -1; + } + } + +- // Wait here until the write is done. This makes +- // hid_get_feature_report() synchronous. ++ /* Wait here until the write is done. This makes ++ hid_get_feature_report() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/); + if (!res) { +- // The operation failed. ++ /* The operation failed. */ + register_error(dev, "Send Feature Report GetOverLappedResult"); + return -1; + } ++ ++ /* bytes_returned does not include the first byte which contains the ++ report ID. The data buffer actually contains one more byte than ++ bytes_returned. */ ++ bytes_returned++; ++ + return bytes_returned; + #endif + } +@@ -736,18 +811,14 @@ void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) + if (!dev) + return; + CancelIo(dev->device_handle); +- CloseHandle(dev->ol.hEvent); +- CloseHandle(dev->device_handle); +- LocalFree(dev->last_error_str); +- free(dev->read_buf); +- free(dev); ++ free_hid_device(dev); + } + + int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) + { + BOOL res; + +- res = HidD_GetManufacturerString(dev->device_handle, string, 2 * maxlen); ++ res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetManufacturerString"); + return -1; +@@ -760,7 +831,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wch + { + BOOL res; + +- res = HidD_GetProductString(dev->device_handle, string, 2 * maxlen); ++ res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetProductString"); + return -1; +@@ -773,7 +844,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *de + { + BOOL res; + +- res = HidD_GetSerialNumberString(dev->device_handle, string, 2 * maxlen); ++ res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetSerialNumberString"); + return -1; +@@ -786,7 +857,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int + { + BOOL res; + +- res = HidD_GetIndexedString(dev->device_handle, string_index, string, 2 * maxlen); ++ res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetIndexedString"); + return -1; +@@ -802,10 +873,10 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) + } + + +-//#define PICPGM +-//#define S11 ++/*#define PICPGM*/ ++/*#define S11*/ + #define P32 +-#ifdef S11 ++#ifdef S11 + unsigned short VendorID = 0xa0a0; + unsigned short ProductID = 0x0001; + #endif +@@ -831,36 +902,36 @@ int __cdecl main(int argc, char* argv[]) + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + +- // Set up the command buffer. ++ /* Set up the command buffer. */ + memset(buf,0x00,sizeof(buf)); + buf[0] = 0; + buf[1] = 0x81; ++ + +- +- // Open the device. ++ /* Open the device. */ + int handle = open(VendorID, ProductID, L"12345"); + if (handle < 0) + printf("unable to open device\n"); + + +- // Toggle LED (cmd 0x80) ++ /* Toggle LED (cmd 0x80) */ + buf[1] = 0x80; + res = write(handle, buf, 65); + if (res < 0) + printf("Unable to write()\n"); + +- // Request state (cmd 0x81) ++ /* Request state (cmd 0x81) */ + buf[1] = 0x81; + write(handle, buf, 65); + if (res < 0) + printf("Unable to write() (2)\n"); + +- // Read requested state ++ /* Read requested state */ + read(handle, buf, 65); + if (res < 0) + printf("Unable to read()\n"); + +- // Print out the returned buffer. ++ /* Print out the returned buffer. */ + for (int i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + +@@ -869,5 +940,5 @@ int __cdecl main(int argc, char* argv[]) + #endif + + #ifdef __cplusplus +-} // extern "C" ++} /* extern "C" */ + #endif +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0016-Bug-fix-performance-counter-s-clock-option-i.e.-thre.patch gnuradio-3.7.10.1/debian/patches/0016-Bug-fix-performance-counter-s-clock-option-i.e.-thre.patch --- gnuradio-3.7.10.1/debian/patches/0016-Bug-fix-performance-counter-s-clock-option-i.e.-thre.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0016-Bug-fix-performance-counter-s-clock-option-i.e.-thre.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,50 @@ +From 807bba681d56589d2f02cd6227181d9abc796e17 Mon Sep 17 00:00:00 2001 +From: Pedro Lobo +Date: Mon, 26 Sep 2016 11:45:45 +0200 +Subject: [PATCH 16/20] Bug fix: performance counter's clock option (i.e. + thread or monotonic) was honored only if controlport was enabled. + +--- + gnuradio-runtime/lib/top_block.cc | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/gnuradio-runtime/lib/top_block.cc b/gnuradio-runtime/lib/top_block.cc +index 8918a8f..7d13508 100644 +--- a/gnuradio-runtime/lib/top_block.cc ++++ b/gnuradio-runtime/lib/top_block.cc +@@ -59,6 +59,17 @@ namespace gr { + void + top_block::start(int max_noutput_items) + { ++#ifdef GNURADIO_HRT_USE_CLOCK_GETTIME ++ std::string initial_clock = prefs::singleton()->get_string("PerfCounters", "clock", "thread"); ++ if(initial_clock.compare("thread") == 0){ ++ gr::high_res_timer_source = CLOCK_THREAD_CPUTIME_ID; ++ } else if(initial_clock.compare("monotonic") == 0){ ++ gr::high_res_timer_source = CLOCK_MONOTONIC; ++ } else { ++ throw std::runtime_error("bad argument for PerfCounters.clock!"); ++ } ++#endif ++ + d_impl->start(max_noutput_items); + + if(prefs::singleton()->get_bool("ControlPort", "on", false)) { +@@ -186,14 +197,6 @@ namespace gr { + } + + #ifdef GNURADIO_HRT_USE_CLOCK_GETTIME +- std::string initial_clock = prefs::singleton()->get_string("PerfCounters", "clock", "thread"); +- if(initial_clock.compare("thread") == 0){ +- gr::high_res_timer_source = CLOCK_THREAD_CPUTIME_ID; +- } else if(initial_clock.compare("monotonic") == 0){ +- gr::high_res_timer_source = CLOCK_MONOTONIC; +- } else { +- throw std::runtime_error("bad argument for PerfCounters.clock!"); +- } + add_rpc_variable( + rpcbasic_sptr(new rpcbasic_register_variable_rw( + alias(), "perfcounter_clock", +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0017-qtgui-whitespace-fix-gcc-warning-misleading-indentat.patch gnuradio-3.7.10.1/debian/patches/0017-qtgui-whitespace-fix-gcc-warning-misleading-indentat.patch --- gnuradio-3.7.10.1/debian/patches/0017-qtgui-whitespace-fix-gcc-warning-misleading-indentat.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0017-qtgui-whitespace-fix-gcc-warning-misleading-indentat.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,59 @@ +From 90c88a94945f889445f79c610a5e7d6fc6221310 Mon Sep 17 00:00:00 2001 +From: Sebastian Koslowski +Date: Wed, 28 Sep 2016 11:42:31 +0200 +Subject: [PATCH 17/20] qtgui: whitespace fix (gcc warning + "misleading-indentation") + +--- + gr-qtgui/lib/VectorDisplayPlot.cc | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/gr-qtgui/lib/VectorDisplayPlot.cc b/gr-qtgui/lib/VectorDisplayPlot.cc +index 2babfea..54d5c49 100644 +--- a/gr-qtgui/lib/VectorDisplayPlot.cc ++++ b/gr-qtgui/lib/VectorDisplayPlot.cc +@@ -284,12 +284,12 @@ void VectorDisplayPlot::setYAxisLabel(const QString &label) + + void VectorDisplayPlot::setXAxisUnit(const QString &unit) + { +- ((VectorDisplayZoomer*)d_zoomer)->setXUnits(unit); ++ ((VectorDisplayZoomer*)d_zoomer)->setXUnits(unit); + } + + void VectorDisplayPlot::setYAxisUnit(const QString &unit) + { +- ((VectorDisplayZoomer*)d_zoomer)->setYUnits(unit); ++ ((VectorDisplayZoomer*)d_zoomer)->setYUnits(unit); + } + + void +@@ -301,17 +301,17 @@ VectorDisplayPlot::setXAxisValues( + if((start != d_x_axis_start) || (step != d_x_axis_step)) + reset = true; + +- d_x_axis_start = start; +- d_x_axis_step = step; ++ d_x_axis_start = start; ++ d_x_axis_step = step; + +- if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (d_zoomer != NULL)) { +- setAxisTitle(QwtPlot::xBottom, d_x_axis_label); +- if(reset) { +- _resetXAxisPoints(); +- clearMaxData(); +- clearMinData(); +- } ++ if((axisScaleDraw(QwtPlot::xBottom) != NULL) && (d_zoomer != NULL)) { ++ setAxisTitle(QwtPlot::xBottom, d_x_axis_label); ++ if(reset) { ++ _resetXAxisPoints(); ++ clearMaxData(); ++ clearMinData(); + } ++ } + } + + void +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0018-runtime-connect-message-ports-after-unlock.patch gnuradio-3.7.10.1/debian/patches/0018-runtime-connect-message-ports-after-unlock.patch --- gnuradio-3.7.10.1/debian/patches/0018-runtime-connect-message-ports-after-unlock.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0018-runtime-connect-message-ports-after-unlock.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,32 @@ +From cce68f26f1641c0a97b0bbc9a4608903aed493c7 Mon Sep 17 00:00:00 2001 +From: Bastian Bloessl +Date: Fri, 30 Sep 2016 06:52:22 +0200 +Subject: [PATCH 18/20] runtime: connect message ports after unlock() + +--- + gnuradio-runtime/lib/flat_flowgraph.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/gnuradio-runtime/lib/flat_flowgraph.cc b/gnuradio-runtime/lib/flat_flowgraph.cc +index 434a92f..b7e9491 100644 +--- a/gnuradio-runtime/lib/flat_flowgraph.cc ++++ b/gnuradio-runtime/lib/flat_flowgraph.cc +@@ -316,6 +316,15 @@ namespace gr { + setup_buffer_alignment(block); + } + ++ // Connect message ports connetions ++ for(msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++) { ++ if(FLAT_FLOWGRAPH_DEBUG) ++ std::cout << boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") % ++ i->src().block() % i->src().port() % ++ i->dst().block() % i->dst().port(); ++ i->src().block()->message_port_sub(i->src().port(), pmt::cons(i->dst().block()->alias_pmt(), i->dst().port())); ++ } ++ + // Now deal with the fact that the block details might have + // changed numbers of inputs and outputs vs. in the old + // flowgraph. +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0019-runtime-add-qa-for-flowgraph.patch gnuradio-3.7.10.1/debian/patches/0019-runtime-add-qa-for-flowgraph.patch --- gnuradio-3.7.10.1/debian/patches/0019-runtime-add-qa-for-flowgraph.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0019-runtime-add-qa-for-flowgraph.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,77 @@ +From 3ba6a665bc0b60c709eeaddce47dcfb92436357f Mon Sep 17 00:00:00 2001 +From: Bastian Bloessl +Date: Sat, 1 Oct 2016 10:03:25 +0200 +Subject: [PATCH 19/20] runtime: add qa for flowgraph + +--- + .../python/gnuradio/gr/qa_flowgraph.py | 58 ++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + create mode 100755 gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py + +diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py b/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py +new file mode 100755 +index 0000000..fa4fd49 +--- /dev/null ++++ b/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py +@@ -0,0 +1,58 @@ ++#!/usr/bin/env python ++# ++# Copyright 2016 Free Software Foundation, Inc. ++# ++# This file is part of GNU Radio ++# ++# GNU Radio 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. ++# ++# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to ++# the Free Software Foundation, Inc., 51 Franklin Street, ++# Boston, MA 02110-1301, USA. ++# ++ ++import time ++import pmt ++from gnuradio import gr, gr_unittest, blocks ++ ++class test_flowgraph (gr_unittest.TestCase): ++ ++ def setUp (self): ++ self.tb = gr.top_block () ++ ++ def tearDown (self): ++ self.tb = None ++ ++ def test_000(self): ++ ++ self.tb.start() ++ self.tb.lock() ++ ++ rem = blocks.pdu_remove(pmt.intern('foo')) ++ dbg = blocks.message_debug() ++ self.tb.msg_connect((rem, 'pdus'), (dbg, 'store')) ++ ++ self.tb.unlock() ++ ++ msg = pmt.cons(pmt.PMT_NIL, pmt.init_u8vector(3, (1, 2, 3))) ++ rem.to_basic_block()._post(pmt.intern('pdus'), msg) ++ time.sleep(0.2) ++ ++ self.tb.stop() ++ ++ self.assertEqual(dbg.num_messages(), 1) ++ data = pmt.u8vector_elements(pmt.cdr(dbg.get_message(0))) ++ self.assertEqual((1, 2, 3), data) ++ ++if __name__ == '__main__': ++ gr_unittest.run(test_flowgraph, 'test_flowgraph.xml') ++ +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/0020-Qt-time-sink-now-respects-tag-color-from-QSS-stylesh.patch gnuradio-3.7.10.1/debian/patches/0020-Qt-time-sink-now-respects-tag-color-from-QSS-stylesh.patch --- gnuradio-3.7.10.1/debian/patches/0020-Qt-time-sink-now-respects-tag-color-from-QSS-stylesh.patch 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/0020-Qt-time-sink-now-respects-tag-color-from-QSS-stylesh.patch 2016-10-09 20:07:17.000000000 +0000 @@ -0,0 +1,39 @@ +From 8d8fffafb20c5d894e478ded9111f1a503131ef1 Mon Sep 17 00:00:00 2001 +From: Johannes Demel +Date: Wed, 28 Sep 2016 18:07:39 +0200 +Subject: [PATCH 20/20] Qt time sink now respects tag color from QSS stylesheet + +--- + gr-qtgui/lib/TimeDomainDisplayPlot.cc | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc +index bc9f630..51a1989 100644 +--- a/gr-qtgui/lib/TimeDomainDisplayPlot.cc ++++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc +@@ -343,9 +343,7 @@ TimeDomainDisplayPlot::plotNewData(const std::vector dataPoints, + m->setXValue(sample_offset); + m->setYValue(yval); + +- QBrush brush; +- brush.setColor(QColor(0xC8, 0x2F, 0x1F)); +- brush.setStyle(Qt::SolidPattern); ++ QBrush brush(getTagBackgroundColor(), getTagBackgroundStyle()); + + QPen pen; + pen.setColor(Qt::black); +@@ -367,8 +365,10 @@ TimeDomainDisplayPlot::plotNewData(const std::vector dataPoints, + #else + m->setSymbol(sym); + #endif ++ QwtText tag_label(s.str().c_str()); ++ tag_label.setColor(getTagTextColor()); ++ m->setLabel(tag_label); + +- m->setLabel(QwtText(s.str().c_str())); + m->attach(this); + + if(!(show && d_tag_markers_en[which])) { +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/Convert-tabs-to-spaces gnuradio-3.7.10.1/debian/patches/Convert-tabs-to-spaces --- gnuradio-3.7.10.1/debian/patches/Convert-tabs-to-spaces 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/Convert-tabs-to-spaces 2016-10-10 02:14:06.000000000 +0000 @@ -0,0 +1,209 @@ +From 4f7241de0cfa4ae5d2468a01d1a46fe446c43a80 Mon Sep 17 00:00:00 2001 +From: Clayton Smith +Date: Fri, 16 Sep 2016 12:00:16 -0600 +Subject: [PATCH 2/3] Convert tabs to spaces. + +--- + gr-vocoder/include/gnuradio/vocoder/freedv_api.h | 12 +++---- + gr-vocoder/lib/freedv_rx_ss_impl.cc | 40 ++++++++++++------------ + gr-vocoder/lib/freedv_rx_ss_impl.h | 6 ++-- + gr-vocoder/lib/freedv_tx_ss_impl.cc | 16 +++++----- + gr-vocoder/lib/freedv_tx_ss_impl.h | 4 +-- + 5 files changed, 39 insertions(+), 39 deletions(-) + +diff --git a/gr-vocoder/include/gnuradio/vocoder/freedv_api.h b/gr-vocoder/include/gnuradio/vocoder/freedv_api.h +index 52fbc63..230da4e 100644 +--- a/gr-vocoder/include/gnuradio/vocoder/freedv_api.h ++++ b/gr-vocoder/include/gnuradio/vocoder/freedv_api.h +@@ -39,22 +39,22 @@ namespace gr { + + enum freedv_modes { + #ifdef FREEDV_MODE_1600 +- MODE_1600 = FREEDV_MODE_1600, ++ MODE_1600 = FREEDV_MODE_1600, + #endif + #ifdef FREEDV_MODE_700 +- MODE_700 = FREEDV_MODE_700, ++ MODE_700 = FREEDV_MODE_700, + #endif + #ifdef FREEDV_MODE_700B +- MODE_700B = FREEDV_MODE_700B, ++ MODE_700B = FREEDV_MODE_700B, + #endif + #ifdef FREEDV_MODE_2400A +- MODE_2400A = FREEDV_MODE_2400A, ++ MODE_2400A = FREEDV_MODE_2400A, + #endif + #ifdef FREEDV_MODE_2400B +- MODE_2400B = FREEDV_MODE_2400B, ++ MODE_2400B = FREEDV_MODE_2400B, + #endif + #ifdef FREEDV_MODE_800XA +- MODE_800XA = FREEDV_MODE_800XA, ++ MODE_800XA = FREEDV_MODE_800XA, + #endif + }; + +diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.cc b/gr-vocoder/lib/freedv_rx_ss_impl.cc +index 6cb52ef..06a8967 100644 +--- a/gr-vocoder/lib/freedv_rx_ss_impl.cc ++++ b/gr-vocoder/lib/freedv_rx_ss_impl.cc +@@ -50,17 +50,17 @@ namespace gr { + freedv_rx_ss::make(int mode, float squelch_thresh) + { + return gnuradio::get_initial_sptr +- (new freedv_rx_ss_impl(mode, squelch_thresh)); ++ (new freedv_rx_ss_impl(mode, squelch_thresh)); + } + + freedv_rx_ss_impl::freedv_rx_ss_impl (int mode, float squelch_thresh) + : gr::block("vocoder_freedv_rx_ss", +- io_signature::make(1, 1, sizeof(short)), +- io_signature::make(1, 1, sizeof(short))), +- d_mode(mode), d_squelch_thresh(squelch_thresh) ++ io_signature::make(1, 1, sizeof(short)), ++ io_signature::make(1, 1, sizeof(short))), ++ d_mode(mode), d_squelch_thresh(squelch_thresh) + { + if((d_freedv = freedv_open(mode)) == NULL) +- throw std::runtime_error("freedv_rx_ss_impl: freedv_open failed"); ++ throw std::runtime_error("freedv_rx_ss_impl: freedv_open failed"); + freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh); + freedv_set_squelch_en(d_freedv, 0); + freedv_set_callback_txt(d_freedv, put_next_rx_char, NULL, (void *) &d_cb_state); +@@ -85,18 +85,18 @@ namespace gr { + + void + freedv_rx_ss_impl::forecast(int noutput_items, +- gr_vector_int &ninput_items_required) ++ gr_vector_int &ninput_items_required) + { + unsigned ninputs = ninput_items_required.size(); + for(unsigned i = 0; i < ninputs; i++) +- ninput_items_required[i] = noutput_items; ++ ninput_items_required[i] = noutput_items; + } + + int + freedv_rx_ss_impl::general_work(int noutput_items, +- gr_vector_int &ninput_items, +- gr_vector_const_void_star &input_items, +- gr_vector_void_star &output_items) ++ gr_vector_int &ninput_items, ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items) + { + short *in = (short *) input_items[0]; + short *out = (short *) output_items[0]; +@@ -104,20 +104,20 @@ namespace gr { + + d_nin = freedv_nin(d_freedv); + if (ninput_items[0] < d_nin) { +- consume_each(0); +- return(0); ++ consume_each(0); ++ return(0); + } + for (i=0,n=0; ((n+d_nin) <= noutput_items)&&(i <= ninput_items[0]);) { +- d_nout = freedv_rx(d_freedv, out, in); +- i += d_nin; +- n += d_nout; +- out = &(out[d_nout]); +- in = &(in[d_nin]); +- d_nin = freedv_nin(d_freedv); ++ d_nout = freedv_rx(d_freedv, out, in); ++ i += d_nin; ++ n += d_nout; ++ out = &(out[d_nout]); ++ in = &(in[d_nin]); ++ d_nin = freedv_nin(d_freedv); + } + if ((i > ninput_items[0])||((n+d_nin) > noutput_items)) { +- i -= d_nin; +- n -= d_nout; ++ i -= d_nin; ++ n -= d_nout; + } // back up to where we left off processing freedv_rx + + freedv_get_modem_stats(d_freedv, &d_sync, &d_snr_est); +diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.h b/gr-vocoder/lib/freedv_rx_ss_impl.h +index 911355b..acc49d9 100644 +--- a/gr-vocoder/lib/freedv_rx_ss_impl.h ++++ b/gr-vocoder/lib/freedv_rx_ss_impl.h +@@ -70,9 +70,9 @@ namespace gr { + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, +- gr_vector_int &ninput_items, +- gr_vector_const_void_star &input_items, +- gr_vector_void_star &output_items); ++ gr_vector_int &ninput_items, ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items); + }; + + } /* namespace vocoder */ +diff --git a/gr-vocoder/lib/freedv_tx_ss_impl.cc b/gr-vocoder/lib/freedv_tx_ss_impl.cc +index d8cf04d..a375510 100644 +--- a/gr-vocoder/lib/freedv_tx_ss_impl.cc ++++ b/gr-vocoder/lib/freedv_tx_ss_impl.cc +@@ -57,17 +57,17 @@ namespace gr { + freedv_tx_ss::make(int mode, const std::string msg_txt) + { + return gnuradio::get_initial_sptr +- (new freedv_tx_ss_impl(mode, msg_txt)); ++ (new freedv_tx_ss_impl(mode, msg_txt)); + } + + freedv_tx_ss_impl::freedv_tx_ss_impl(int mode, const std::string msg_txt) + : sync_block("vocoder_freedv_tx_ss", +- io_signature::make(1, 1, sizeof(short)), +- io_signature::make(1, 1, sizeof(short))), +- d_mode(mode), d_msg_text(msg_txt) ++ io_signature::make(1, 1, sizeof(short)), ++ io_signature::make(1, 1, sizeof(short))), ++ d_mode(mode), d_msg_text(msg_txt) + { + if((d_freedv = freedv_open(mode)) == NULL) +- throw std::runtime_error("freedv_tx_ss_impl: freedv_open failed"); ++ throw std::runtime_error("freedv_tx_ss_impl: freedv_open failed"); + snprintf(d_cb_state.tx_str,79,"%s",d_msg_text.c_str()); + d_cb_state.ptx_str = d_cb_state.tx_str; + freedv_set_callback_txt(d_freedv, NULL, get_next_tx_char, (void *) &d_cb_state); +@@ -82,15 +82,15 @@ namespace gr { + + int + freedv_tx_ss_impl::work(int noutput_items, +- gr_vector_const_void_star &input_items, +- gr_vector_void_star &output_items) ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items) + { + short *in = (short*)input_items[0]; + short *out = (short*)output_items[0]; + int i; + + for(i=0;i<(noutput_items/d_nom_modem_samples);i++) +- freedv_tx(d_freedv, &(out[i*d_nom_modem_samples]), &(in[i*d_nom_modem_samples])); ++ freedv_tx(d_freedv, &(out[i*d_nom_modem_samples]), &(in[i*d_nom_modem_samples])); + return noutput_items; + } + +diff --git a/gr-vocoder/lib/freedv_tx_ss_impl.h b/gr-vocoder/lib/freedv_tx_ss_impl.h +index 4a24d3b..a023b67 100644 +--- a/gr-vocoder/lib/freedv_tx_ss_impl.h ++++ b/gr-vocoder/lib/freedv_tx_ss_impl.h +@@ -62,8 +62,8 @@ namespace gr { + + // Where all the action really happens + int work(int noutput_items, +- gr_vector_const_void_star &input_items, +- gr_vector_void_star &output_items); ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items); + }; + + } /* namespace vocoder */ +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/freedv-blocks gnuradio-3.7.10.1/debian/patches/freedv-blocks --- gnuradio-3.7.10.1/debian/patches/freedv-blocks 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/freedv-blocks 2016-10-10 02:11:38.000000000 +0000 @@ -0,0 +1,923 @@ +From c19264b23fc007b81a9bda8f9f879f69429c89c3 Mon Sep 17 00:00:00 2001 +From: "A. Maitland Bottoms" +Date: Sun, 26 Jun 2016 21:47:47 -0400 +Subject: [PATCH] add freedv blocks + +--- + gr-vocoder/CMakeLists.txt | 1 + + gr-vocoder/grc/CMakeLists.txt | 9 ++ + gr-vocoder/grc/vocoder_block_tree.xml | 2 + + gr-vocoder/grc/vocoder_freedv_rx_ss.xml | 58 ++++++++ + gr-vocoder/grc/vocoder_freedv_tx_ss.xml | 57 ++++++++ + gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt | 9 ++ + gr-vocoder/include/gnuradio/vocoder/freedv_api.h | 68 +++++++++ + gr-vocoder/include/gnuradio/vocoder/freedv_rx_ss.h | 63 +++++++++ + gr-vocoder/include/gnuradio/vocoder/freedv_tx_ss.h | 59 ++++++++ + gr-vocoder/lib/CMakeLists.txt | 7 + + gr-vocoder/lib/freedv_api.cc | 33 +++++ + gr-vocoder/lib/freedv_rx_ss_impl.cc | 155 +++++++++++++++++++++ + gr-vocoder/lib/freedv_rx_ss_impl.h | 81 +++++++++++ + gr-vocoder/lib/freedv_tx_ss_impl.cc | 98 +++++++++++++ + gr-vocoder/lib/freedv_tx_ss_impl.h | 72 ++++++++++ + gr-vocoder/swig/CMakeLists.txt | 4 + + gr-vocoder/swig/vocoder_swig.i | 19 +++ + 17 files changed, 795 insertions(+) + create mode 100644 gr-vocoder/grc/vocoder_freedv_rx_ss.xml + create mode 100644 gr-vocoder/grc/vocoder_freedv_tx_ss.xml + create mode 100644 gr-vocoder/include/gnuradio/vocoder/freedv_api.h + create mode 100644 gr-vocoder/include/gnuradio/vocoder/freedv_rx_ss.h + create mode 100644 gr-vocoder/include/gnuradio/vocoder/freedv_tx_ss.h + create mode 100644 gr-vocoder/lib/freedv_api.cc + create mode 100644 gr-vocoder/lib/freedv_rx_ss_impl.cc + create mode 100644 gr-vocoder/lib/freedv_rx_ss_impl.h + create mode 100644 gr-vocoder/lib/freedv_tx_ss_impl.cc + create mode 100644 gr-vocoder/lib/freedv_tx_ss_impl.h + +--- a/gr-vocoder/CMakeLists.txt ++++ b/gr-vocoder/CMakeLists.txt +@@ -99,6 +99,7 @@ + #message(STATUS "libcodec2 has 700bps mode") + endif() + if (LIBCODEC2_HAS_FREEDV_API) ++ GR_APPEND_SUBCOMPONENT("freedv") + #message(STATUS "libcodec2 had FreeDV api modes: ${FREEDV_MODES}") + endif() + endif(LIBCODEC2_FOUND) +--- a/gr-vocoder/grc/CMakeLists.txt ++++ b/gr-vocoder/grc/CMakeLists.txt +@@ -46,6 +46,15 @@ + ) + endif(LIBCODEC2_FOUND) + ++if(LIBCODEC2_HAS_FREEDV_API) ++ install(FILES ++ vocoder_freedv_rx_ss.xml ++ vocoder_freedv_tx_ss.xml ++ DESTINATION ${GRC_BLOCKS_DIR} ++ COMPONENT "vocoder_python" ++ ) ++endif(LIBCODEC2_HAS_FREEDV_API) ++ + if(LIBGSM_FOUND) + install(FILES + vocoder_gsm_fr_decode_ps.xml +--- a/gr-vocoder/grc/vocoder_block_tree.xml ++++ b/gr-vocoder/grc/vocoder_block_tree.xml +@@ -38,6 +38,8 @@ + vocoder_cvsd_encode_sb + vocoder_cvsd_decode_bf + vocoder_cvsd_encode_fb ++ vocoder_freedv_tx_ss ++ vocoder_freedv_rx_ss + vocoder_g721_decode_bs + vocoder_g721_encode_sb + vocoder_g723_24_decode_bs +--- /dev/null ++++ b/gr-vocoder/grc/vocoder_freedv_rx_ss.xml +@@ -0,0 +1,58 @@ ++ ++ ++ ++ FreeDV demodulator ++ vocoder_freedv_rx_ss ++ from gnuradio import vocoder ++ from gnuradio.vocoder import freedv_api ++ vocoder.freedv_rx_ss($mode,$squelch_thresh) ++ set_squelch_thresh($squelch_thresh) ++ ++ Operating Mode ++ mode ++ freedv_api.MODE_1600 ++ int ++ ++ ++ ++ ++ ++ ++ ++ ++ Squelch Threshold ++ squelch_thresh ++ -100.0 ++ float ++ ++ ++ in ++ short ++ ++ ++ out ++ short ++ ++ +--- /dev/null ++++ b/gr-vocoder/grc/vocoder_freedv_tx_ss.xml +@@ -0,0 +1,57 @@ ++ ++ ++ ++ FreeDV modulator ++ vocoder_freedv_tx_ss ++ from gnuradio import vocoder ++ from gnuradio.vocoder import freedv_api ++ vocoder.freedv_tx_ss($mode,$txt_msg) ++ ++ Operating Mode ++ mode ++ freedv_api.MODE_1600 ++ int ++ ++ ++ ++ ++ ++ ++ ++ ++ Text Message ++ txt_msg ++ 'GNU Radio' ++ string ++ ++ ++ in ++ short ++ ++ ++ out ++ short ++ ++ +--- a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt ++++ b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt +@@ -46,6 +46,15 @@ + COMPONENT "vocoder_devel" + ) + endif(LIBCODEC2_FOUND) ++if(LIBCODEC2_HAS_FREEDV_API) ++install(FILES ++ freedv_api.h ++ freedv_rx_ss.h ++ freedv_tx_ss.h ++ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder ++ COMPONENT "vocoder_devel" ++) ++endif(LIBCODEC2_HAS_FREEDV_API) + if(LIBGSM_FOUND) + install(FILES + gsm_fr_decode_ps.h +--- /dev/null ++++ b/gr-vocoder/include/gnuradio/vocoder/freedv_api.h +@@ -0,0 +1,68 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifndef _VOCODER_FREEDV_H_ ++#define _VOCODER_FREEDV_H_ ++ ++#include ++ ++extern "C" { ++#include ++#include ++#include ++} ++ ++namespace gr { ++ namespace vocoder { ++ ++ class VOCODER_API freedv_api { ++ public: ++ ++ enum freedv_modes { ++#ifdef FREEDV_MODE_1600 ++ MODE_1600 = FREEDV_MODE_1600, ++#endif ++#ifdef FREEDV_MODE_700 ++ MODE_700 = FREEDV_MODE_700, ++#endif ++#ifdef FREEDV_MODE_700B ++ MODE_700B = FREEDV_MODE_700B, ++#endif ++#ifdef FREEDV_MODE_2400A ++ MODE_2400A = FREEDV_MODE_2400A, ++#endif ++#ifdef FREEDV_MODE_2400B ++ MODE_2400B = FREEDV_MODE_2400B, ++#endif ++#ifdef FREEDV_MODE_800XA ++ MODE_800XA = FREEDV_MODE_800XA, ++#endif ++ }; ++ ++ private: ++ ++ }; ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ ++ ++#endif /* _VOCODER_FREEDV_H_ */ +--- /dev/null ++++ b/gr-vocoder/include/gnuradio/vocoder/freedv_rx_ss.h +@@ -0,0 +1,63 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifndef INCLUDED_VOCODER_FREEDV_RX_H ++#define INCLUDED_VOCODER_FREEDV_RX_H ++ ++#include ++#include ++#include ++ ++namespace gr { ++ namespace vocoder { ++ ++ /*! ++ * \brief FreeDV demodulator ++ * \ingroup audio_blk ++ * ++ * Input: 16-bit short values of an audio signal with sampling rate 8 kHz. ++ * ++ * Output: 16-bit short values of an audio signal with sampling rate 8 kHz. ++ * ++ * See also gr::vocoder::freedv_tx_ss. ++ */ ++ class VOCODER_API freedv_rx_ss : virtual public gr::block ++ { ++ public: ++ typedef boost::shared_ptr sptr; ++ ++ /*! ++ * \brief Make FreeDV modem demodulator block. ++ * ++ * \param mode Operating Mode designation ++ * \param squelch_thresh FreeDV modem squelch threshold value ++ */ ++ static sptr make(int mode=freedv_api::MODE_1600, float squelch_thresh=-100.0); ++ ++ virtual void set_squelch_thresh(float squelch_thresh) = 0; ++ virtual float squelch_thresh() = 0; ++ }; ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ ++ ++#endif /* INCLUDED_VOCODER_FREEDV_RX_H */ +--- /dev/null ++++ b/gr-vocoder/include/gnuradio/vocoder/freedv_tx_ss.h +@@ -0,0 +1,59 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifndef INCLUDED_VOCODER_FREEDV_TX_H ++#define INCLUDED_VOCODER_FREEDV_TX_H ++ ++#include ++#include ++#include ++ ++namespace gr { ++ namespace vocoder { ++ ++ /*! ++ * \brief FreeDV modulator ++ * \ingroup audio_blk ++ * ++ * Input: Speech (audio) signal as 16-bit shorts, sampling rate 8 kHz. ++ * ++ * Output: Signal (audio) as 16-bit shorts, sampling rate 8 kHz. ++ * ++ */ ++ class VOCODER_API freedv_tx_ss : virtual public gr::sync_block ++ { ++ public: ++ typedef boost::shared_ptr sptr; ++ ++ /*! ++ * \brief Make FreeDV Modem modulator block. ++ * ++ * \param mode Operating Mode designation ++ * \param msg_txt Low Rate message text (callsign, location) ++ */ ++ static sptr make(int mode=freedv_api::MODE_1600,const std::string msg_txt="GNU Radio"); ++ }; ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ ++ ++#endif /* INCLUDED_VOCODER_FREEDV_TX_H */ +--- a/gr-vocoder/lib/CMakeLists.txt ++++ b/gr-vocoder/lib/CMakeLists.txt +@@ -61,6 +61,13 @@ + codec2_encode_sp_impl.cc + ) + endif(LIBCODEC2_FOUND) ++if(LIBCODEC2_HAS_FREEDV_API) ++ list(APPEND gr_vocoder_sources ++ freedv_api.cc ++ freedv_rx_ss_impl.cc ++ freedv_tx_ss_impl.cc ++ ) ++endif(LIBCODEC2_HAS_FREEDV_API) + if(LIBGSM_FOUND) + list(APPEND gr_vocoder_sources + gsm_fr_decode_ps_impl.cc +--- /dev/null ++++ b/gr-vocoder/lib/freedv_api.cc +@@ -0,0 +1,33 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; 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 ++#endif ++ ++#include ++ ++namespace gr { ++ namespace vocoder { ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ +--- /dev/null ++++ b/gr-vocoder/lib/freedv_rx_ss_impl.cc +@@ -0,0 +1,155 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; 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 "freedv_rx_ss_impl.h" ++ ++#include ++#include ++#include ++ ++extern "C" { ++ void put_next_rx_char(void *callback_state, char c) { ++ struct freedv_rx_callback_state* pstate; ++ ++ pstate = (struct freedv_rx_callback_state*) callback_state; ++ if (pstate->ftxt != NULL) { ++ //fprintf(pstate->ftxt, "%c\n", c); ++ } ++ return; ++ } ++} ++ ++ ++namespace gr { ++ namespace vocoder { ++ ++ freedv_rx_ss::sptr ++ freedv_rx_ss::make(int mode, float squelch_thresh) ++ { ++ return gnuradio::get_initial_sptr ++ (new freedv_rx_ss_impl(mode, squelch_thresh)); ++ } ++ ++ freedv_rx_ss_impl::freedv_rx_ss_impl (int mode, float squelch_thresh) ++ : gr::block("vocoder_freedv_rx_ss", ++ io_signature::make(1, 1, sizeof(short)), ++ io_signature::make(1, 1, sizeof(short))), ++ d_mode(mode), d_squelch_thresh(squelch_thresh) ++ { ++ if((d_freedv = freedv_open(mode)) == NULL) ++ throw std::runtime_error("freedv_rx_ss_impl: freedv_open failed"); ++ freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh); ++ freedv_set_squelch_en(d_freedv, 0); ++ freedv_set_callback_txt(d_freedv, put_next_rx_char, NULL, (void *) &d_cb_state); ++ d_speech_samples = freedv_get_n_speech_samples(d_freedv); ++ d_max_modem_samples = freedv_get_n_max_modem_samples(d_freedv); ++ d_nin = freedv_nin(d_freedv); ++ //set_output_multiple(d_max_modem_samples); ++ } ++ ++ freedv_rx_ss_impl::~freedv_rx_ss_impl() ++ { ++ int total_bits; ++ int total_bit_errors; ++ ++ if (freedv_get_test_frames(d_freedv)) { ++ total_bits = freedv_get_total_bits(d_freedv); ++ total_bit_errors = freedv_get_total_bit_errors(d_freedv); ++ fprintf(stderr, "bits: %d errors: %d BER: %3.2f\n", total_bits, total_bit_errors, (1.0*total_bit_errors)/total_bits); ++ } ++ freedv_close(d_freedv); ++ } ++ ++ void ++ freedv_rx_ss_impl::forecast(int noutput_items, ++ gr_vector_int &ninput_items_required) ++ { ++ unsigned ninputs = ninput_items_required.size(); ++ for(unsigned i = 0; i < ninputs; i++) ++ ninput_items_required[i] = noutput_items; ++ } ++ ++ int ++ freedv_rx_ss_impl::general_work(int noutput_items, ++ gr_vector_int &ninput_items, ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items) ++ { ++ short *in = (short *) input_items[0]; ++ short *out = (short *) output_items[0]; ++ int i,n; ++ ++ d_nin = freedv_nin(d_freedv); ++ if (ninput_items[0] < d_nin) { ++ consume_each(0); ++ return(0); ++ } ++ for (i=0,n=0; ((n+d_nin) <= noutput_items)&&(i <= ninput_items[0]);) { ++ d_nout = freedv_rx(d_freedv, out, in); ++ i += d_nin; ++ n += d_nout; ++ out = &(out[d_nout]); ++ in = &(in[d_nin]); ++ d_nin = freedv_nin(d_freedv); ++ } ++ if ((i > ninput_items[0])||((n+d_nin) > noutput_items)) { ++ i -= d_nin; ++ n -= d_nout; ++ } // back up to where we left off processing freedv_rx ++ ++ freedv_get_modem_stats(d_freedv, &d_sync, &d_snr_est); ++ freedv_get_modem_extended_stats(d_freedv, &d_stats); ++ d_total_bit_errors = freedv_get_total_bit_errors(d_freedv); ++ ++ consume_each(i); ++ return(n); ++ } ++ ++ void put_next_rx_proto(void *callback_state,char *proto_bits) { ++ return; ++ } ++ ++ void datarx(void *callback_state, unsigned char *packet, size_t size) { ++ return; ++ } ++ ++ void datatx(void *callback_state, unsigned char *packet, size_t *size) { ++ return; ++ } ++ ++ void freedv_rx_ss_impl::set_squelch_thresh(float squelch_thresh) ++ { ++ gr::thread::scoped_lock l(d_setlock); ++ d_squelch_thresh = squelch_thresh; ++ freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh); ++ } ++ ++ float freedv_rx_ss_impl::squelch_thresh() { ++ return(d_squelch_thresh); ++ } ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ +--- /dev/null ++++ b/gr-vocoder/lib/freedv_rx_ss_impl.h +@@ -0,0 +1,81 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifndef INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H ++#define INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H ++ ++#include ++ ++extern "C" { ++ struct freedv_rx_callback_state { ++ FILE *ftxt; ++ }; ++ static void put_next_rx_char(void *callback_state, char c); ++ void put_next_rx_proto(void *callback_state,char *proto_bits); ++ void datarx(void *callback_state, unsigned char *packet, size_t size); ++ void datatx(void *callback_state, unsigned char *packet, size_t *size); ++} ++ ++namespace gr { ++ namespace vocoder { ++ ++ class freedv_rx_ss_impl : public freedv_rx_ss ++ { ++ private: ++ short *d_speech_out; ++ short *d_demod_in; ++ struct freedv *d_freedv; ++ int d_nin, d_nout, d_frame; ++ struct freedv_rx_callback_state d_cb_state; ++ struct MODEM_STATS d_stats; ++ int d_mode; ++ int d_sync; ++ int d_total_bits; ++ int d_total_bit_errors; ++ float d_snr_est; ++ float d_squelch_thresh; ++ int d_speech_samples; ++ int d_max_modem_samples; ++ float d_clock_offset; ++ int d_use_codecrx; ++ struct CODEC2 *d_c2 = NULL; ++ ++ public: ++ freedv_rx_ss_impl(int mode, float squelch_thresh); ++ ~freedv_rx_ss_impl(); ++ ++ void set_squelch_thresh(float squelch_thresh); ++ float squelch_thresh(); ++ ++ // Where all the action really happens ++ void forecast(int noutput_items, gr_vector_int &ninput_items_required); ++ ++ int general_work(int noutput_items, ++ gr_vector_int &ninput_items, ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items); ++ }; ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ ++ ++#endif /* INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H */ +--- /dev/null ++++ b/gr-vocoder/lib/freedv_tx_ss_impl.cc +@@ -0,0 +1,98 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; 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 "freedv_tx_ss_impl.h" ++ ++#include ++#include ++#include ++#include ++ ++extern "C" { ++ char ++ get_next_tx_char(void *callback_state) ++ { ++ char c; ++ struct freedv_tx_callback_state* pstate; ++ ++ pstate = (struct freedv_tx_callback_state*)callback_state; ++ c = *pstate->ptx_str++; ++ ++ if (*pstate->ptx_str == 0) { ++ pstate->ptx_str = pstate->tx_str; ++ c = 0x0d; // FreeDV uses Carriage Return termination ++ } ++ ++ return c; ++ } ++} ++ ++namespace gr { ++ namespace vocoder { ++ ++ freedv_tx_ss::sptr ++ freedv_tx_ss::make(int mode, const std::string msg_txt) ++ { ++ return gnuradio::get_initial_sptr ++ (new freedv_tx_ss_impl(mode, msg_txt)); ++ } ++ ++ freedv_tx_ss_impl::freedv_tx_ss_impl(int mode, const std::string msg_txt) ++ : sync_block("vocoder_freedv_tx_ss", ++ io_signature::make(1, 1, sizeof(short)), ++ io_signature::make(1, 1, sizeof(short))), ++ d_mode(mode), d_msg_text(msg_txt) ++ { ++ if((d_freedv = freedv_open(mode)) == NULL) ++ throw std::runtime_error("freedv_tx_ss_impl: freedv_open failed"); ++ snprintf(d_cb_state.tx_str,79,"%s",d_msg_text.c_str()); ++ d_cb_state.ptx_str = d_cb_state.tx_str; ++ freedv_set_callback_txt(d_freedv, NULL, get_next_tx_char, (void *) &d_cb_state); ++ d_nom_modem_samples = freedv_get_n_nom_modem_samples(d_freedv); ++ set_output_multiple(d_nom_modem_samples); ++ } ++ ++ freedv_tx_ss_impl::~freedv_tx_ss_impl() ++ { ++ freedv_close(d_freedv); ++ } ++ ++ int ++ freedv_tx_ss_impl::work(int noutput_items, ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items) ++ { ++ short *in = (short*)input_items[0]; ++ short *out = (short*)output_items[0]; ++ int i; ++ ++ for(i=0;i<(noutput_items/d_nom_modem_samples);i++) ++ freedv_tx(d_freedv, &(out[i*d_nom_modem_samples]), &(in[i*d_nom_modem_samples])); ++ return noutput_items; ++ } ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ +--- /dev/null ++++ b/gr-vocoder/lib/freedv_tx_ss_impl.h +@@ -0,0 +1,72 @@ ++/* -*- c++ -*- */ ++/* ++ * Copyright 2016 Free Software Foundation, Inc. ++ * ++ * This file is part of GNU Radio ++ * ++ * GNU Radio 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. ++ * ++ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to ++ * the Free Software Foundation, Inc., 51 Franklin Street, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifndef INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H ++#define INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H ++ ++#include ++ ++extern "C" { ++ struct freedv_tx_callback_state { ++ char tx_str[80]; ++ char *ptx_str; ++ int calls; ++ }; ++ char get_next_tx_char(void *callback_state); ++ void get_next_proto(void *callback_state,char *proto_bits); ++ void datarx(void *callback_state, unsigned char *packet, size_t size); ++ void datatx(void *callback_state, unsigned char *packet, size_t *size); ++} ++ ++namespace gr { ++ namespace vocoder { ++ ++ class freedv_tx_ss_impl : public freedv_tx_ss ++ { ++ private: ++ short *d_speech_in; ++ short *d_mod_out; ++ struct freedv_tx_callback_state d_cb_state; ++ struct freedv *d_freedv; ++ int d_mode; ++ float d_squelch_thresh; ++ int d_speech_samples; ++ int d_nom_modem_samples; ++ int d_use_codectx; ++ int d_use_datatx; ++ std::string d_msg_text; ++ struct CODEC2 *d_c2; ++ ++ public: ++ freedv_tx_ss_impl(int mode, const std::string txt_msg); ++ ~freedv_tx_ss_impl(); ++ ++ // Where all the action really happens ++ int work(int noutput_items, ++ gr_vector_const_void_star &input_items, ++ gr_vector_void_star &output_items); ++ }; ++ ++ } /* namespace vocoder */ ++} /* namespace gr */ ++ ++#endif /* INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H */ +--- a/gr-vocoder/swig/CMakeLists.txt ++++ b/gr-vocoder/swig/CMakeLists.txt +@@ -37,6 +37,10 @@ + list(APPEND GR_SWIG_FLAGS "-DLIBCODEC2_FOUND") + endif(LIBCODEC2_FOUND) + ++if(LIBCODEC2_HAS_FREEDV_API) ++ list(APPEND GR_SWIG_FLAGS "-DLIBCODEC2_HAS_FREEDV_API") ++endif(LIBCODEC2_HAS_FREEDV_API) ++ + if(LIBGSM_FOUND) + list(APPEND GR_SWIG_FLAGS "-DLIBGSM_FOUND") + endif(LIBGSM_FOUND) +--- a/gr-vocoder/swig/vocoder_swig.i ++++ b/gr-vocoder/swig/vocoder_swig.i +@@ -85,6 +85,25 @@ + GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_encode_sp); + #endif + ++#ifdef LIBCODEC2_HAS_FREEDV_API ++%{ ++#include ++#include "gnuradio/vocoder/freedv_api.h" ++#include "gnuradio/vocoder/freedv_rx_ss.h" ++#include "gnuradio/vocoder/freedv_tx_ss.h" ++%} ++ ++%ignore freedv_set_smooth_symbols; ++%ignore freedv_set_clip; ++%include ++%include "gnuradio/vocoder/freedv_api.h" ++%include "gnuradio/vocoder/freedv_rx_ss.h" ++%include "gnuradio/vocoder/freedv_tx_ss.h" ++ ++GR_SWIG_BLOCK_MAGIC2(vocoder, freedv_rx_ss); ++GR_SWIG_BLOCK_MAGIC2(vocoder, freedv_tx_ss); ++#endif ++ + #ifdef LIBGSM_FOUND + %{ + #include "gnuradio/vocoder/gsm_fr_decode_ps.h" diff -Nru gnuradio-3.7.10.1/debian/patches/Get-the-FreeDV-demodulator-working gnuradio-3.7.10.1/debian/patches/Get-the-FreeDV-demodulator-working --- gnuradio-3.7.10.1/debian/patches/Get-the-FreeDV-demodulator-working 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/Get-the-FreeDV-demodulator-working 2016-10-10 02:14:06.000000000 +0000 @@ -0,0 +1,76 @@ +From 71962d82886b0635e0654ea1db6967894c24f4f5 Mon Sep 17 00:00:00 2001 +From: Clayton Smith +Date: Fri, 16 Sep 2016 14:33:46 -0600 +Subject: [PATCH 3/3] Get the FreeDV demodulator working. + +--- + gr-vocoder/lib/freedv_rx_ss_impl.cc | 31 +++++++++++-------------------- + 1 file changed, 11 insertions(+), 20 deletions(-) + +diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.cc b/gr-vocoder/lib/freedv_rx_ss_impl.cc +index 06a8967..748a5c1 100644 +--- a/gr-vocoder/lib/freedv_rx_ss_impl.cc ++++ b/gr-vocoder/lib/freedv_rx_ss_impl.cc +@@ -67,7 +67,7 @@ namespace gr { + d_speech_samples = freedv_get_n_speech_samples(d_freedv); + d_max_modem_samples = freedv_get_n_max_modem_samples(d_freedv); + d_nin = freedv_nin(d_freedv); +- //set_output_multiple(d_max_modem_samples); ++ set_output_multiple(d_max_modem_samples); + } + + freedv_rx_ss_impl::~freedv_rx_ss_impl() +@@ -89,7 +89,7 @@ namespace gr { + { + unsigned ninputs = ninput_items_required.size(); + for(unsigned i = 0; i < ninputs; i++) +- ninput_items_required[i] = noutput_items; ++ ninput_items_required[i] = std::max(d_nin, noutput_items); + } + + int +@@ -100,32 +100,23 @@ namespace gr { + { + short *in = (short *) input_items[0]; + short *out = (short *) output_items[0]; +- int i,n; + +- d_nin = freedv_nin(d_freedv); +- if (ninput_items[0] < d_nin) { +- consume_each(0); +- return(0); +- } +- for (i=0,n=0; ((n+d_nin) <= noutput_items)&&(i <= ninput_items[0]);) { +- d_nout = freedv_rx(d_freedv, out, in); +- i += d_nin; +- n += d_nout; +- out = &(out[d_nout]); +- in = &(in[d_nin]); ++ int in_offset = 0, out_offset = 0; ++ ++ while ((noutput_items - out_offset) >= d_max_modem_samples ++ && (ninput_items[0] - in_offset) >= d_nin) { ++ d_nout = freedv_rx(d_freedv, out + out_offset, in + in_offset); ++ out_offset += d_nout; ++ in_offset += d_nin; + d_nin = freedv_nin(d_freedv); + } +- if ((i > ninput_items[0])||((n+d_nin) > noutput_items)) { +- i -= d_nin; +- n -= d_nout; +- } // back up to where we left off processing freedv_rx + + freedv_get_modem_stats(d_freedv, &d_sync, &d_snr_est); + freedv_get_modem_extended_stats(d_freedv, &d_stats); + d_total_bit_errors = freedv_get_total_bit_errors(d_freedv); + +- consume_each(i); +- return(n); ++ consume_each(in_offset); ++ return out_offset; + } + + void put_next_rx_proto(void *callback_state,char *proto_bits) { +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/provide-example-grfreedv.grc-flowgraph gnuradio-3.7.10.1/debian/patches/provide-example-grfreedv.grc-flowgraph --- gnuradio-3.7.10.1/debian/patches/provide-example-grfreedv.grc-flowgraph 1970-01-01 00:00:00.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/provide-example-grfreedv.grc-flowgraph 2016-10-10 02:14:06.000000000 +0000 @@ -0,0 +1,648 @@ +From 609ec6e8d145cc2b6e8a5cc8c160158df7943a09 Mon Sep 17 00:00:00 2001 +From: "A. Maitland Bottoms" +Date: Thu, 15 Sep 2016 15:12:16 -0400 +Subject: [PATCH 1/3] provide example grfreedv.grc flowgraph + +--- + gr-vocoder/examples/CMakeLists.txt | 1 + + gr-vocoder/examples/grfreedv.grc | 616 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 617 insertions(+) + create mode 100644 gr-vocoder/examples/grfreedv.grc + +diff --git a/gr-vocoder/examples/CMakeLists.txt b/gr-vocoder/examples/CMakeLists.txt +index 0957d81..54b3c7a 100644 +--- a/gr-vocoder/examples/CMakeLists.txt ++++ b/gr-vocoder/examples/CMakeLists.txt +@@ -37,6 +37,7 @@ if(LIBCODEC2_FOUND) + GR_PYTHON_INSTALL( + PROGRAMS + codec2_audio_loopback.py ++ grfreedv.grc + DESTINATION ${GR_PKG_VOCODER_EXAMPLES_DIR} + COMPONENT "vocoder_examples" + ) +diff --git a/gr-vocoder/examples/grfreedv.grc b/gr-vocoder/examples/grfreedv.grc +new file mode 100644 +index 0000000..9f6b95d +--- /dev/null ++++ b/gr-vocoder/examples/grfreedv.grc +@@ -0,0 +1,616 @@ ++ ++ ++ ++ Wed Jun 29 19:22:27 2016 ++ ++ options ++ ++ author ++ A. MAitland Bottoms ++ ++ ++ window_size ++ ++ ++ ++ category ++ Custom ++ ++ ++ comment ++ ++ ++ ++ description ++ A FreeDV Modulator ++ ++ ++ _enabled ++ True ++ ++ ++ _coordinate ++ (8, 8) ++ ++ ++ _rotation ++ 0 ++ ++ ++ generate_options ++ qt_gui ++ ++ ++ hier_block_src_path ++ .: ++ ++ ++ id ++ grfreedv ++ ++ ++ max_nouts ++ 0 ++ ++ ++ qt_qss_theme ++ ++ ++ ++ realtime_scheduling ++ ++ ++ ++ run_command ++ {python} -u {filename} ++ ++ ++ run_options ++ prompt ++ ++ ++ run ++ True ++ ++ ++ thread_safe_setters ++ ++ ++ ++ title ++ GNU Radio FreeDV ++ ++ ++ ++ variable ++ ++ comment ++ ++ ++ ++ _enabled ++ True ++ ++ ++ _coordinate ++ (8, 160) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ samp_rate ++ ++ ++ value ++ 8000 ++ ++ ++ ++ variable_qtgui_range ++ ++ comment ++ ++ ++ ++ value ++ -120 ++ ++ ++ _enabled ++ True ++ ++ ++ _coordinate ++ (232, 16) ++ ++ ++ gui_hint ++ ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ squelch ++ ++ ++ label ++ squelch slider ++ ++ ++ min_len ++ 256 ++ ++ ++ orient ++ Qt.Horizontal ++ ++ ++ start ++ -127 ++ ++ ++ step ++ 1 ++ ++ ++ stop ++ 128 ++ ++ ++ rangeType ++ float ++ ++ ++ widget ++ counter_slider ++ ++ ++ ++ audio_sink ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ device_name ++ ++ ++ ++ _enabled ++ True ++ ++ ++ _coordinate ++ (920, 228) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ audio_sink_0 ++ ++ ++ num_inputs ++ 1 ++ ++ ++ ok_to_block ++ True ++ ++ ++ samp_rate ++ samp_rate ++ ++ ++ ++ audio_source ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ device_name ++ hw:2,0 ++ ++ ++ _enabled ++ 0 ++ ++ ++ _coordinate ++ (16, 325) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ audio_source_0 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ num_outputs ++ 1 ++ ++ ++ ok_to_block ++ True ++ ++ ++ samp_rate ++ 48000 ++ ++ ++ ++ blocks_float_to_short ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ _enabled ++ 1 ++ ++ ++ _coordinate ++ (256, 228) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ blocks_float_to_short_0 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ scale ++ 32768 ++ ++ ++ vlen ++ 1 ++ ++ ++ ++ blocks_short_to_float ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ _enabled ++ 1 ++ ++ ++ _coordinate ++ (736, 228) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ blocks_short_to_float_0 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ scale ++ 32768 ++ ++ ++ vlen ++ 1 ++ ++ ++ ++ blocks_wavfile_source ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ _enabled ++ 1 ++ ++ ++ file ++ /usr/share/codec2/wav/all.wav ++ ++ ++ _coordinate ++ (24, 221) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ blocks_wavfile_source_0 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ nchan ++ 1 ++ ++ ++ repeat ++ True ++ ++ ++ ++ rational_resampler_xxx ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ decim ++ 6 ++ ++ ++ _enabled ++ 0 ++ ++ ++ fbw ++ 0 ++ ++ ++ _coordinate ++ (216, 303) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ rational_resampler_xxx_0 ++ ++ ++ interp ++ 1 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ taps ++ ++ ++ ++ type ++ fff ++ ++ ++ ++ vocoder_freedv_rx_ss ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ _enabled ++ 1 ++ ++ ++ _coordinate ++ (576, 325) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ vocoder_freedv_rx_ss_0 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ mode ++ freedv_api.MODE_1600 ++ ++ ++ squelch_thresh ++ squelch ++ ++ ++ ++ vocoder_freedv_tx_ss ++ ++ alias ++ ++ ++ ++ comment ++ ++ ++ ++ affinity ++ ++ ++ ++ _enabled ++ 1 ++ ++ ++ _coordinate ++ (424, 221) ++ ++ ++ _rotation ++ 0 ++ ++ ++ id ++ vocoder_freedv_tx_ss_0 ++ ++ ++ maxoutbuf ++ 0 ++ ++ ++ minoutbuf ++ 0 ++ ++ ++ mode ++ freedv_api.MODE_1600 ++ ++ ++ txt_msg ++ 'GNU Radio' ++ ++ ++ ++ audio_source_0 ++ rational_resampler_xxx_0 ++ 0 ++ 0 ++ ++ ++ blocks_float_to_short_0 ++ vocoder_freedv_tx_ss_0 ++ 0 ++ 0 ++ ++ ++ blocks_short_to_float_0 ++ audio_sink_0 ++ 0 ++ 0 ++ ++ ++ blocks_wavfile_source_0 ++ blocks_float_to_short_0 ++ 0 ++ 0 ++ ++ ++ rational_resampler_xxx_0 ++ blocks_float_to_short_0 ++ 0 ++ 0 ++ ++ ++ vocoder_freedv_rx_ss_0 ++ blocks_short_to_float_0 ++ 0 ++ 0 ++ ++ ++ vocoder_freedv_tx_ss_0 ++ vocoder_freedv_rx_ss_0 ++ 0 ++ 0 ++ ++ +-- +2.1.4 + diff -Nru gnuradio-3.7.10.1/debian/patches/series gnuradio-3.7.10.1/debian/patches/series --- gnuradio-3.7.10.1/debian/patches/series 2016-08-27 04:06:08.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/series 2016-10-10 02:15:44.000000000 +0000 @@ -4,9 +4,22 @@ 0004-fix-temporary-variable-return-in-userconf_path.patch 0005-move-fec-polar-decoder-D_LLR_FACTOR-into-cpp.patch 0006-dark.qss-cause-forced-on-data-lines-to-die-in-a-fire.patch +0007-gr-dtv-Delete-incorrect-assert-and-useless-set_relat.patch +0008-grc-backwards-compatibility-fix-for-pygtk-2.16-cento.patch +0009-uhd-Fix-order-of-include-dirs.patch +0010-qtgui-Fix-bug-in-trackerText-for-Frequency-Sink.patch +0011-qtgui-Fix-Axis-Labels-checkbox-Control-Panel-checkbo.patch +0012-qtgui-Fix-control-panel-FFT-average-slider-value-syn.patch +0013-dtv-fixed-usage-of-uninitialized-memory-for-data_siz.patch +0014-qtgui-c-example-cmake-fix.patch +0015-fcd-Update-hidapi-to-latest-HEAD.patch +0016-Bug-fix-performance-counter-s-clock-option-i.e.-thre.patch +0017-qtgui-whitespace-fix-gcc-warning-misleading-indentat.patch +0018-runtime-connect-message-ports-after-unlock.patch +0019-runtime-add-qa-for-flowgraph.patch +0020-Qt-time-sink-now-respects-tag-color-from-QSS-stylesh.patch debian-soname usr-bin-examples -bsd-fcd bsd-shm bsd-hurd-alsa bsd-hurd-no-thread-affinity @@ -20,3 +33,7 @@ gr-vocoder-codec2-subcomponent-using-external-codec2 gr-vocoder-gsm-subcomponent-using-external-gsm fix-vocoder-test +freedv-blocks +provide-example-grfreedv.grc-flowgraph +Convert-tabs-to-spaces +Get-the-FreeDV-demodulator-working diff -Nru gnuradio-3.7.10.1/debian/patches/usr-bin-examples gnuradio-3.7.10.1/debian/patches/usr-bin-examples --- gnuradio-3.7.10.1/debian/patches/usr-bin-examples 2016-07-06 22:24:24.000000000 +0000 +++ gnuradio-3.7.10.1/debian/patches/usr-bin-examples 2016-10-10 02:06:32.000000000 +0000 @@ -33,7 +33,7 @@ ) --- a/gr-qtgui/examples/c++/CMakeLists.txt +++ b/gr-qtgui/examples/c++/CMakeLists.txt -@@ -44,6 +44,6 @@ +@@ -43,6 +43,6 @@ INSTALL(TARGETS display_qt