Merge branch 'release' into agc_and_csma
This commit is contained in:
@@ -97,6 +97,13 @@ if(NOT ITPP_FOUND)
|
|||||||
message(FATAL_ERROR "ITPP required to compile ieee802-11")
|
message(FATAL_ERROR "ITPP required to compile ieee802-11")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Setup logging options
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
include(GrMiscUtils)
|
||||||
|
GR_LOGGING()
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# On Apple only, set install name and use rpath correctly, if not already set
|
# On Apple only, set install name and use rpath correctly, if not already set
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -128,12 +135,14 @@ include_directories(
|
|||||||
${CPPUNIT_INCLUDE_DIRS}
|
${CPPUNIT_INCLUDE_DIRS}
|
||||||
${ITPP_INCLUDE_DIR}
|
${ITPP_INCLUDE_DIR}
|
||||||
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||||
|
${LOG4CPP_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
link_directories(
|
link_directories(
|
||||||
${Boost_LIBRARY_DIRS}
|
${Boost_LIBRARY_DIRS}
|
||||||
${CPPUNIT_LIBRARY_DIRS}
|
${CPPUNIT_LIBRARY_DIRS}
|
||||||
${GNURADIO_RUNTIME_LIBRARY_DIRS}
|
${GNURADIO_RUNTIME_LIBRARY_DIRS}
|
||||||
|
${LOG4CPP_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
title: gr-ieee802-11
|
||||||
|
author:
|
||||||
|
- Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
|
copyright_owner:
|
||||||
|
- Bastian Bloessl
|
||||||
|
dependencies:
|
||||||
|
- gnuradio (>= 3.7.4)
|
||||||
|
repo: https://github.com/bastibl/gr-ieee802-11.git
|
||||||
|
tags:
|
||||||
|
- IEEE 802.11
|
||||||
|
- WiFi
|
||||||
|
- OFDM
|
||||||
|
website: http://www.ccs-labs.org/projects/wime/
|
||||||
|
brief: IEEE 802.11 a/g/p Transceiver
|
||||||
|
icon: http://www.ccs-labs.org/projects/wime/wime.png
|
||||||
|
---
|
||||||
|
This an IEEE 802.11 a/g/p transceiver for GNU Radio v3.7. Over the air, I tested it with the Ettus USRP N210 with XCVR2450 and CBX daughterboards. For interoperability tests I use mainly an Atheros (ath5k) WiFi card. The code can also be used for packet error rate simulations.
|
||||||
@@ -64,6 +64,10 @@ To actually install the blocks do
|
|||||||
sudo make install
|
sudo make install
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
|
|
||||||
|
### Adjust Maximum Shared Memory
|
||||||
|
Since the transmitter is using the Tagged Stream blocks it has to store a complete frame in the buffer before processing it. The default maximum shared memory might not be enough on most Linux systems. It can be increased with
|
||||||
|
|
||||||
|
sudo sysctl -w kernel.shmmax=2147483648
|
||||||
|
|
||||||
### OFDM PHY
|
### OFDM PHY
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# - Find Log4cpp
|
||||||
|
# Find the native LOG4CPP includes and library
|
||||||
|
#
|
||||||
|
# LOG4CPP_INCLUDE_DIR - where to find LOG4CPP.h, etc.
|
||||||
|
# LOG4CPP_LIBRARIES - List of libraries when using LOG4CPP.
|
||||||
|
# LOG4CPP_FOUND - True if LOG4CPP found.
|
||||||
|
|
||||||
|
|
||||||
|
if (LOG4CPP_INCLUDE_DIR)
|
||||||
|
# Already in cache, be silent
|
||||||
|
set(LOG4CPP_FIND_QUIETLY TRUE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
find_path(LOG4CPP_INCLUDE_DIR log4cpp/Category.hh
|
||||||
|
/opt/local/include
|
||||||
|
/usr/local/include
|
||||||
|
/usr/include
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LOG4CPP_NAMES log4cpp)
|
||||||
|
find_library(LOG4CPP_LIBRARY
|
||||||
|
NAMES ${LOG4CPP_NAMES}
|
||||||
|
PATHS /usr/lib /usr/local/lib /opt/local/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if (LOG4CPP_INCLUDE_DIR AND LOG4CPP_LIBRARY)
|
||||||
|
set(LOG4CPP_FOUND TRUE)
|
||||||
|
set(LOG4CPP_LIBRARIES ${LOG4CPP_LIBRARY} CACHE INTERNAL "" FORCE)
|
||||||
|
set(LOG4CPP_INCLUDE_DIRS ${LOG4CPP_INCLUDE_DIR} CACHE INTERNAL "" FORCE)
|
||||||
|
else ()
|
||||||
|
set(LOG4CPP_FOUND FALSE CACHE INTERNAL "" FORCE)
|
||||||
|
set(LOG4CPP_LIBRARY "" CACHE INTERNAL "" FORCE)
|
||||||
|
set(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
|
||||||
|
set(LOG4CPP_INCLUDE_DIR "" CACHE INTERNAL "" FORCE)
|
||||||
|
set(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (LOG4CPP_FOUND)
|
||||||
|
if (NOT LOG4CPP_FIND_QUIETLY)
|
||||||
|
message(STATUS "Found LOG4CPP: ${LOG4CPP_LIBRARIES}")
|
||||||
|
endif ()
|
||||||
|
else ()
|
||||||
|
if (LOG4CPP_FIND_REQUIRED)
|
||||||
|
message(STATUS "Looked for LOG4CPP libraries named ${LOG4CPPS_NAMES}.")
|
||||||
|
message(FATAL_ERROR "Could NOT find LOG4CPP library")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
mark_as_advanced(
|
||||||
|
LOG4CPP_LIBRARIES
|
||||||
|
LOG4CPP_INCLUDE_DIRS
|
||||||
|
)
|
||||||
+882
-659
File diff suppressed because it is too large
Load Diff
+1040
-869
File diff suppressed because it is too large
Load Diff
+1483
-1229
File diff suppressed because it is too large
Load Diff
+1302
-940
File diff suppressed because it is too large
Load Diff
+600
-375
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,24 @@
|
|||||||
<key>ieee802_11_ofdm_equalize_symbols</key>
|
<key>ieee802_11_ofdm_equalize_symbols</key>
|
||||||
<category>IEEE802.11</category>
|
<category>IEEE802.11</category>
|
||||||
<import>import ieee802_11</import>
|
<import>import ieee802_11</import>
|
||||||
<make>ieee802_11.ofdm_equalize_symbols($debug)</make>
|
<make>ieee802_11.ofdm_equalize_symbols($algo, $debug)</make>
|
||||||
|
<callback>set_algorithm($algo)</callback>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Algorithm</name>
|
||||||
|
<key>algo</key>
|
||||||
|
<value>ieee802_11.LINEAR_COMB</value>
|
||||||
|
<type>int</type>
|
||||||
|
|
||||||
|
<option>
|
||||||
|
<name>LMS</name>
|
||||||
|
<key>ieee802_11.LMS</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>linear comb</name>
|
||||||
|
<key>ieee802_11.LINEAR_COMB</key>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Debug</name>
|
<name>Debug</name>
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<block>
|
|
||||||
<name>OFDM Freq Est</name>
|
|
||||||
<key>ieee802_11_ofdm_freq_est</key>
|
|
||||||
<category>IEEE802.11</category>
|
|
||||||
<import>import ieee802_11</import>
|
|
||||||
<make>ieee802_11.ofdm_freq_est($log, $debug)</make>
|
|
||||||
|
|
||||||
<param>
|
|
||||||
<name>Log</name>
|
|
||||||
<key>log</key>
|
|
||||||
<value>False</value>
|
|
||||||
<type>bool</type>
|
|
||||||
|
|
||||||
<option>
|
|
||||||
<name>Enable</name>
|
|
||||||
<key>True</key>
|
|
||||||
</option>
|
|
||||||
<option>
|
|
||||||
<name>Disable</name>
|
|
||||||
<key>False</key>
|
|
||||||
</option>
|
|
||||||
</param>
|
|
||||||
|
|
||||||
<param>
|
|
||||||
<name>Debug</name>
|
|
||||||
<key>debug</key>
|
|
||||||
<value>False</value>
|
|
||||||
<type>bool</type>
|
|
||||||
|
|
||||||
<option>
|
|
||||||
<name>Enable</name>
|
|
||||||
<key>True</key>
|
|
||||||
</option>
|
|
||||||
<option>
|
|
||||||
<name>Disable</name>
|
|
||||||
<key>False</key>
|
|
||||||
</option>
|
|
||||||
</param>
|
|
||||||
|
|
||||||
<sink>
|
|
||||||
<name>in</name>
|
|
||||||
<type>complex</type>
|
|
||||||
<nports>1</nports>
|
|
||||||
</sink>
|
|
||||||
|
|
||||||
<source>
|
|
||||||
<name>out</name>
|
|
||||||
<type>complex</type>
|
|
||||||
<nports>1</nports>
|
|
||||||
</source>
|
|
||||||
|
|
||||||
</block>
|
|
||||||
@@ -11,8 +11,41 @@
|
|||||||
<param>
|
<param>
|
||||||
<name>Encoding</name>
|
<name>Encoding</name>
|
||||||
<key>encoding</key>
|
<key>encoding</key>
|
||||||
<value>0</value>
|
<value>ieee802_11.BPSK_1_2</value>
|
||||||
<type>int</type>
|
<type>int</type>
|
||||||
|
|
||||||
|
<option>
|
||||||
|
<name>BPSK 1/2</name>
|
||||||
|
<key>ieee802_11.BPSK_1_2</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>BPSK 3/4</name>
|
||||||
|
<key>ieee802_11.BPSK_3_4</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>QPSK 1/2</name>
|
||||||
|
<key>ieee802_11.QPSK_1_2</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>QPSK 3/4</name>
|
||||||
|
<key>ieee802_11.QPSK_3_4</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>16QAM 1/2</name>
|
||||||
|
<key>ieee802_11.16QAM_1_2</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>16QAM 3/4</name>
|
||||||
|
<key>ieee802_11.16QAM_3_4</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>64QAM 2/3</name>
|
||||||
|
<key>ieee802_11.64QAM_2_3</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>64QAM 3/4</name>
|
||||||
|
<key>ieee802_11.64QAM_3_4</key>
|
||||||
|
</option>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
|
|||||||
@@ -44,5 +44,11 @@
|
|||||||
<type>message</type>
|
<type>message</type>
|
||||||
</sink>
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>fer</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
|
||||||
</block>
|
</block>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<key>ieee802_11_ofdm_sync_short</key>
|
<key>ieee802_11_ofdm_sync_short</key>
|
||||||
<category>IEEE802.11</category>
|
<category>IEEE802.11</category>
|
||||||
<import>import ieee802_11</import>
|
<import>import ieee802_11</import>
|
||||||
<make>ieee802_11.ofdm_sync_short($threshold, $max_samples, $min_plateau, $log, $debug)</make>
|
<make>ieee802_11.ofdm_sync_short($threshold, $min_plateau, $log, $debug)</make>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Log</name>
|
<name>Log</name>
|
||||||
@@ -46,13 +46,6 @@
|
|||||||
<type>real</type>
|
<type>real</type>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
<param>
|
|
||||||
<name>Max Samples</name>
|
|
||||||
<key>max_samples</key>
|
|
||||||
<value>5200</value>
|
|
||||||
<type>int</type>
|
|
||||||
</param>
|
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Min Plateau</name>
|
<name>Min Plateau</name>
|
||||||
<key>min_plateau</key>
|
<key>min_plateau</key>
|
||||||
@@ -61,7 +54,6 @@
|
|||||||
</param>
|
</param>
|
||||||
|
|
||||||
<check>$threshold > 0</check>
|
<check>$threshold > 0</check>
|
||||||
<check>$max_samples > 400</check>
|
|
||||||
<check>$min_plateau > 0</check>
|
<check>$min_plateau > 0</check>
|
||||||
|
|
||||||
<sink>
|
<sink>
|
||||||
@@ -70,6 +62,12 @@
|
|||||||
<nports>1</nports>
|
<nports>1</nports>
|
||||||
</sink>
|
</sink>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>abs</name>
|
||||||
|
<type>complex</type>
|
||||||
|
<nports>1</nports>
|
||||||
|
</sink>
|
||||||
|
|
||||||
<sink>
|
<sink>
|
||||||
<name>cor</name>
|
<name>cor</name>
|
||||||
<type>float</type>
|
<type>float</type>
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ list(APPEND include_sources
|
|||||||
ofdm_decode_mac.h
|
ofdm_decode_mac.h
|
||||||
ofdm_decode_signal.h
|
ofdm_decode_signal.h
|
||||||
ofdm_equalize_symbols.h
|
ofdm_equalize_symbols.h
|
||||||
ofdm_freq_est.h
|
|
||||||
ofdm_mac.h
|
ofdm_mac.h
|
||||||
ofdm_mapper.h
|
ofdm_mapper.h
|
||||||
ofdm_parse_mac.h
|
ofdm_parse_mac.h
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
* Copyright (C) 2013, 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,6 +20,11 @@
|
|||||||
#include <ieee802-11/api.h>
|
#include <ieee802-11/api.h>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
enum Equalizer {
|
||||||
|
LMS = 0,
|
||||||
|
LINEAR_COMB = 1,
|
||||||
|
};
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace ieee802_11 {
|
namespace ieee802_11 {
|
||||||
|
|
||||||
@@ -28,7 +33,8 @@ class IEEE802_11_API ofdm_equalize_symbols : virtual public block
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ofdm_equalize_symbols> sptr;
|
typedef boost::shared_ptr<ofdm_equalize_symbols> sptr;
|
||||||
static sptr make(bool debug = false);
|
static sptr make(Equalizer algo, bool debug = false);
|
||||||
|
virtual void set_algorithm(Equalizer algo) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ class IEEE802_11_API ofdm_sync_short : virtual public block
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ofdm_sync_short> sptr;
|
typedef boost::shared_ptr<ofdm_sync_short> sptr;
|
||||||
static sptr make(double threshold, unsigned int max_samples,
|
static sptr make(double threshold, unsigned int min_plateau, bool log = false, bool debug = false);
|
||||||
unsigned int min_plateau, bool log = false, bool debug = false);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -94,12 +94,13 @@ add_dependencies(ieee802_11_generated_sources ieee802_11_generated_includes)
|
|||||||
########################################################################
|
########################################################################
|
||||||
list(APPEND gr_ieee802_11_sources
|
list(APPEND gr_ieee802_11_sources
|
||||||
${generated_sources}
|
${generated_sources}
|
||||||
|
equalizer/linear_comb.cc
|
||||||
|
equalizer/lms.cc
|
||||||
chunks_to_symbols_impl.cc
|
chunks_to_symbols_impl.cc
|
||||||
ether_encap_impl.cc
|
ether_encap_impl.cc
|
||||||
ofdm_decode_mac.cc
|
ofdm_decode_mac.cc
|
||||||
ofdm_decode_signal.cc
|
ofdm_decode_signal.cc
|
||||||
ofdm_equalize_symbols.cc
|
ofdm_equalize_symbols.cc
|
||||||
ofdm_freq_est.cc
|
|
||||||
ofdm_mac.cc
|
ofdm_mac.cc
|
||||||
ofdm_mapper.cc
|
ofdm_mapper.cc
|
||||||
ofdm_parse_mac.cc
|
ofdm_parse_mac.cc
|
||||||
@@ -115,6 +116,7 @@ list(APPEND gr_ieee802_11_libs
|
|||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${GNURADIO_ALL_LIBRARIES}
|
${GNURADIO_ALL_LIBRARIES}
|
||||||
${ITPP_LIBRARIES}
|
${ITPP_LIBRARIES}
|
||||||
|
${LOG4CPP_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(gnuradio-ieee802_11 SHARED ${gr_ieee802_11_sources})
|
add_library(gnuradio-ieee802_11 SHARED ${gr_ieee802_11_sources})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,25 +14,24 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef INCLUDED_IEEE802_11_OFDM_FREQ_EST_H
|
|
||||||
#define INCLUDED_IEEE802_11_OFDM_FREQ_EST_H
|
|
||||||
|
|
||||||
#include <ieee802-11/api.h>
|
#ifndef INCLUDED_IEEE802_11_EQUALIZER_BASE_H
|
||||||
#include <gnuradio/block.h>
|
#define INCLUDED_IEEE802_11_EQUALIZER_BASE_H
|
||||||
|
|
||||||
|
#include <gnuradio/gr_complex.h>
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace ieee802_11 {
|
namespace ieee802_11 {
|
||||||
|
namespace equalizer {
|
||||||
|
|
||||||
class IEEE802_11_API ofdm_freq_est : virtual public block
|
class base {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~base() {};
|
||||||
typedef boost::shared_ptr<ofdm_freq_est> sptr;
|
virtual void equalize(const gr_complex *in, gr_complex *out, int n) = 0;
|
||||||
static sptr make(bool log = false, bool debug = false);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ieee802_11
|
} /* namespace channel_estimation */
|
||||||
} // namespace gr
|
} /* namespace ieee802_11 */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
||||||
#endif /* INCLUDED_IEEE802_11_OFDM_FREQ_EST_H */
|
#endif /* INCLUDED_IEEE802_11_EQUALIZER_BASE_H */
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "linear_comb.h"
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11::equalizer;
|
||||||
|
|
||||||
|
void linear_comb::equalize(const gr_complex *in, gr_complex *out, int n) {
|
||||||
|
if(n < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double avg_mag = (abs(in[11]) + abs(in[25]) + abs(in[39]) + abs(in[53])) / 4;
|
||||||
|
|
||||||
|
gr_complex p = POLARITY[(n - 2) % 127 ];
|
||||||
|
|
||||||
|
double p1 = arg( p * in[11]);
|
||||||
|
double p2 = arg( p * in[25] * conj(p * in[11])) + p1;
|
||||||
|
double p3 = arg( p * in[39] * conj(p * in[25])) + p2;
|
||||||
|
double p4 = arg(-p * in[53] * conj(p * in[39])) + p3;
|
||||||
|
|
||||||
|
double my = (p1 + p2 + p3 + p4) / 4;
|
||||||
|
double mx = (11.0 + 25 + 39 + 53) / 4;
|
||||||
|
|
||||||
|
double var = (((11.0 * 11.0) + (25.0 * 25.0) + (39.0 * 39.0) + (53.0 * 53.0)) / 4) - (mx * mx);
|
||||||
|
double cov = (( (p1 * 11) + (p2 * 25) + (p3 * 39) + (p4 * 53) ) / 4) - (mx * my);
|
||||||
|
double beta = cov / var;
|
||||||
|
double alpha = my - beta * mx;
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
for(int n = 0; n < 64; n++) {
|
||||||
|
if( (n == 11) || (n == 25) || (n == 32) || (n == 39) || (n == 53) || (n < 6) || ( n > 58)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
out[c] = in[n] * exp(gr_complex(0, -n * beta - alpha)) * gr_complex(1 / avg_mag, 0);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const gr_complex linear_comb::POLARITY[127] = {
|
||||||
|
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
|
||||||
|
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
|
||||||
|
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
|
||||||
|
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
|
||||||
|
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
|
||||||
|
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
|
||||||
|
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
|
||||||
|
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H
|
||||||
|
#define INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H
|
||||||
|
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
namespace equalizer {
|
||||||
|
|
||||||
|
class linear_comb: public base {
|
||||||
|
public:
|
||||||
|
virtual void equalize(const gr_complex *in, gr_complex *out, int n);
|
||||||
|
private:
|
||||||
|
static const gr_complex POLARITY[127];
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace channel_estimation */
|
||||||
|
} /* namespace ieee802_11 */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LINEAR_COMB_H */
|
||||||
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lms.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11::equalizer;
|
||||||
|
|
||||||
|
void lms::equalize(const gr_complex *in, gr_complex *out, int n) {
|
||||||
|
|
||||||
|
static float freq_offset = 0;
|
||||||
|
static float freq_sum = 0;
|
||||||
|
static float alpha = 0.9;
|
||||||
|
|
||||||
|
if(n == 0) {
|
||||||
|
std::memcpy(carrier, in, 64 * sizeof(gr_complex));
|
||||||
|
} else if(n == 1) {
|
||||||
|
gr_complex sum =
|
||||||
|
(carrier[11] * conj(in[11])) +
|
||||||
|
(carrier[25] * conj(in[25])) +
|
||||||
|
(carrier[39] * conj(in[39])) +
|
||||||
|
(carrier[53] * conj(in[53]));
|
||||||
|
freq_offset = arg(sum);
|
||||||
|
freq_sum = 0;
|
||||||
|
for(int i = 0; i < 64; i++) {
|
||||||
|
carrier[i] += in[i];
|
||||||
|
carrier[i] *= ref[i] * gr_complex(0.5, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
gr_complex p = POLARITY[(n - 2) % 127];
|
||||||
|
gr_complex sum =
|
||||||
|
(carrier[11] * conj(in[11]) * p) +
|
||||||
|
(carrier[25] * conj(in[25]) * p) +
|
||||||
|
(carrier[39] * conj(in[39]) * p) +
|
||||||
|
(carrier[53] * conj(in[53]) * -p);
|
||||||
|
|
||||||
|
freq_offset = (1 - alpha) * freq_offset + alpha * arg(sum);
|
||||||
|
freq_sum += freq_offset;
|
||||||
|
|
||||||
|
//std::cout << "lms: symbol " << n
|
||||||
|
// << " p1 " << abs(carrier[11] * conj(in[11]) * p)
|
||||||
|
// << " p2 " << abs(carrier[25] * conj(in[25]) * p)
|
||||||
|
// << " p3 " << abs(carrier[39] * conj(in[39]) * p)
|
||||||
|
// << " p4 " << abs(carrier[53] * conj(in[53]) * -p)
|
||||||
|
// << std::endl;
|
||||||
|
//std::cout << "lms: symbol " << n
|
||||||
|
// << " p1 " << arg(carrier[11] * conj(in[11]) * p)
|
||||||
|
// << " p2 " << arg(carrier[25] * conj(in[25]) * p)
|
||||||
|
// << " p3 " << arg(carrier[39] * conj(in[39]) * p)
|
||||||
|
// << " p4 " << arg(carrier[53] * conj(in[53]) * -p)
|
||||||
|
// << std::endl;
|
||||||
|
|
||||||
|
carrier[11] = in[11] * p;
|
||||||
|
carrier[25] = in[25] * p;
|
||||||
|
carrier[39] = in[39] * p;
|
||||||
|
carrier[53] = in[53] * -p;
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
for(int i = 0; i < 64; i++) {
|
||||||
|
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
out[c] = in[i] / carrier[i] * exp(gr_complex(0, freq_sum));
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const gr_complex lms::ref[] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1, -1, -1,
|
||||||
|
1, 1, -1, 1, -1, 1, 1, 1, 1, 1,
|
||||||
|
1, -1, -1, 1, 1, -1, 1, -1, 1, 1,
|
||||||
|
1, 1, 0, 1, -1, -1, 1, 1, -1, 1,
|
||||||
|
-1, 1, -1, -1, -1, -1, -1, 1, 1, -1,
|
||||||
|
-1, 1, -1, 1, -1, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const gr_complex lms::POLARITY[127] = {
|
||||||
|
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
|
||||||
|
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
|
||||||
|
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
|
||||||
|
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
|
||||||
|
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
|
||||||
|
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
|
||||||
|
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
|
||||||
|
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_IEEE802_11_EQUALIZER_LMS_H
|
||||||
|
#define INCLUDED_IEEE802_11_EQUALIZER_LMS_H
|
||||||
|
|
||||||
|
#include "base.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
namespace equalizer {
|
||||||
|
|
||||||
|
class lms: public base {
|
||||||
|
public:
|
||||||
|
virtual void equalize(const gr_complex *in, gr_complex *out, int n);
|
||||||
|
private:
|
||||||
|
gr_complex carrier[64];
|
||||||
|
static const gr_complex ref[64];
|
||||||
|
static const gr_complex POLARITY[127];
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace channel_estimation */
|
||||||
|
} /* namespace ieee802_11 */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LMS_H */
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ ether_encap_impl::from_wifi(pmt::pmt_t msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is more than neeed
|
// this is more than needed
|
||||||
char *buf = static_cast<char*>(std::malloc(data_len + sizeof(ethernet_header)));
|
char *buf = static_cast<char*>(std::malloc(data_len + sizeof(ethernet_header)));
|
||||||
ethernet_header *ehdr = reinterpret_cast<ethernet_header*>(buf);
|
ethernet_header *ehdr = reinterpret_cast<ethernet_header*>(buf);
|
||||||
|
|
||||||
|
|||||||
+46
-34
@@ -34,8 +34,9 @@ ofdm_decode_mac_impl(bool log, bool debug) : block("ofdm_decode_mac",
|
|||||||
gr::io_signature::make(0, 0, 0)),
|
gr::io_signature::make(0, 0, 0)),
|
||||||
d_log(log),
|
d_log(log),
|
||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
ofdm(BPSK_1_2),
|
d_ofdm(BPSK_1_2),
|
||||||
tx(ofdm, 0) {
|
d_tx(d_ofdm, 0),
|
||||||
|
d_frame_complete(true) {
|
||||||
|
|
||||||
message_port_register_out(pmt::mp("out"));
|
message_port_register_out(pmt::mp("out"));
|
||||||
|
|
||||||
@@ -82,34 +83,43 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
pmt::string_to_symbol("ofdm_start"));
|
pmt::string_to_symbol("ofdm_start"));
|
||||||
|
|
||||||
if(tags.size()) {
|
if(tags.size()) {
|
||||||
|
if (d_frame_complete == false) {
|
||||||
|
dout << "Warning: starting to receive new frame before old frame was complete" << std::endl;
|
||||||
|
dout << "Already copied " << copied << " out of " << d_tx.n_sym << " symbols of last frame" << std::endl;
|
||||||
|
}
|
||||||
|
d_frame_complete = false;
|
||||||
|
|
||||||
pmt::pmt_t tuple = tags[0].value;
|
pmt::pmt_t tuple = tags[0].value;
|
||||||
int len_data = pmt::to_uint64(pmt::car(tuple));
|
int len_data = pmt::to_uint64(pmt::car(tuple));
|
||||||
int encoding = pmt::to_uint64(pmt::cdr(tuple));
|
int encoding = pmt::to_uint64(pmt::cdr(tuple));
|
||||||
|
|
||||||
ofdm = ofdm_param((Encoding)encoding);
|
ofdm_param ofdm = ofdm_param((Encoding)encoding);
|
||||||
tx = tx_param(ofdm, len_data);
|
tx_param tx = tx_param(ofdm, len_data);
|
||||||
|
|
||||||
copied = 0;
|
// sanity check, more than MAX_SYM may indicate garbage
|
||||||
|
if(tx.n_sym <= MAX_SYM && tx.n_encoded_bits <= MAX_BITS) {
|
||||||
// this frame is garbage
|
d_ofdm = ofdm;
|
||||||
if(tx.n_sym > 100) {
|
d_tx = tx;
|
||||||
// FIXME: make this nicer, this way garbage frames are skipped
|
copied = 0;
|
||||||
copied = tx.n_sym + 1;
|
dout << "Decode MAC: frame start -- len " << len_data
|
||||||
|
<< " symbols " << tx.n_sym << " encoding "
|
||||||
|
<< encoding << std::endl;
|
||||||
|
} else {
|
||||||
|
dout << "Dropping frame which is too large (symbols or bits)" << std::endl;
|
||||||
}
|
}
|
||||||
dout << "Decode MAC: frame start -- len " << len_data
|
|
||||||
<< " symbols " << tx.n_sym << " encoding "
|
|
||||||
<< encoding << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(copied < tx.n_sym) {
|
if(copied < d_tx.n_sym) {
|
||||||
|
dout << "copy one symbol, copied " << copied << " out of " << d_tx.n_sym << std::endl;
|
||||||
std::memcpy(sym + (copied * 48), in, 48 * sizeof(gr_complex));
|
std::memcpy(sym + (copied * 48), in, 48 * sizeof(gr_complex));
|
||||||
copied++;
|
copied++;
|
||||||
|
|
||||||
if(copied == tx.n_sym) {
|
if(copied == d_tx.n_sym) {
|
||||||
dout << "received complete frame - decoding" << std::endl;
|
dout << "received complete frame - decoding" << std::endl;
|
||||||
decode();
|
decode();
|
||||||
in += 48;
|
in += 48;
|
||||||
i++;
|
i++;
|
||||||
|
d_frame_complete = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,18 +141,18 @@ void decode() {
|
|||||||
|
|
||||||
// skip service field
|
// skip service field
|
||||||
boost::crc_32_type result;
|
boost::crc_32_type result;
|
||||||
result.process_bytes(out_bytes + 2, tx.psdu_size);
|
result.process_bytes(out_bytes + 2, d_tx.psdu_size);
|
||||||
if(result.checksum() != 558161692) {
|
if(result.checksum() != 558161692) {
|
||||||
dout << "checksum wrong -- dropping" << std::endl;
|
dout << "checksum wrong -- dropping" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||||
% ofdm.encoding % tx.psdu_size % tx.n_sym);
|
% d_ofdm.encoding % d_tx.psdu_size % d_tx.n_sym);
|
||||||
|
|
||||||
// create PDU
|
// create PDU
|
||||||
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, tx.psdu_size - 4);
|
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_tx.psdu_size - 4);
|
||||||
pmt::pmt_t enc = pmt::from_uint64(ofdm.encoding);
|
pmt::pmt_t enc = pmt::from_uint64(d_ofdm.encoding);
|
||||||
pmt::pmt_t dict = pmt::make_dict();
|
pmt::pmt_t dict = pmt::make_dict();
|
||||||
dict = pmt::dict_add(dict, pmt::mp("encoding"), enc);
|
dict = pmt::dict_add(dict, pmt::mp("encoding"), enc);
|
||||||
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
|
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
|
||||||
@@ -151,12 +161,12 @@ void decode() {
|
|||||||
void demodulate() {
|
void demodulate() {
|
||||||
|
|
||||||
cvec symbols;
|
cvec symbols;
|
||||||
symbols.set_length(tx.n_sym * 48);
|
symbols.set_length(d_tx.n_sym * 48);
|
||||||
for(int i = 0; i < tx.n_sym * 48; i++) {
|
for(int i = 0; i < d_tx.n_sym * 48; i++) {
|
||||||
symbols[i] = std::complex<double>(sym[i]);
|
symbols[i] = std::complex<double>(sym[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(ofdm.encoding) {
|
switch(d_ofdm.encoding) {
|
||||||
case BPSK_1_2:
|
case BPSK_1_2:
|
||||||
case BPSK_3_4:
|
case BPSK_3_4:
|
||||||
|
|
||||||
@@ -185,10 +195,10 @@ void demodulate() {
|
|||||||
|
|
||||||
void deinterleave() {
|
void deinterleave() {
|
||||||
|
|
||||||
int n_cbps = ofdm.n_cbps;
|
int n_cbps = d_ofdm.n_cbps;
|
||||||
int first[n_cbps];
|
int first[n_cbps];
|
||||||
int second[n_cbps];
|
int second[n_cbps];
|
||||||
int s = std::max(ofdm.n_bpsc / 2, 1);
|
int s = std::max(d_ofdm.n_bpsc / 2, 1);
|
||||||
|
|
||||||
for(int j = 0; j < n_cbps; j++) {
|
for(int j = 0; j < n_cbps; j++) {
|
||||||
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
||||||
@@ -198,7 +208,7 @@ void deinterleave() {
|
|||||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < tx.n_sym; i++) {
|
for(int i = 0; i < d_tx.n_sym; i++) {
|
||||||
for(int k = 0; k < n_cbps; k++) {
|
for(int k = 0; k < n_cbps; k++) {
|
||||||
deinter[i * n_cbps + second[first[k]]] = bits[i * n_cbps + k];
|
deinter[i * n_cbps + second[first[k]]] = bits[i * n_cbps + k];
|
||||||
}
|
}
|
||||||
@@ -213,7 +223,7 @@ void decode_conv() {
|
|||||||
code.set_generator_polynomials(generator, 7);
|
code.set_generator_polynomials(generator, 7);
|
||||||
|
|
||||||
bmat puncture_matrix;
|
bmat puncture_matrix;
|
||||||
switch(ofdm.encoding) {
|
switch(d_ofdm.encoding) {
|
||||||
case BPSK_1_2:
|
case BPSK_1_2:
|
||||||
case QPSK_1_2:
|
case QPSK_1_2:
|
||||||
case QAM16_1_2:
|
case QAM16_1_2:
|
||||||
@@ -233,12 +243,12 @@ void decode_conv() {
|
|||||||
code.set_truncation_length(30);
|
code.set_truncation_length(30);
|
||||||
|
|
||||||
dout << "coding rate " << code.get_rate() << std::endl;
|
dout << "coding rate " << code.get_rate() << std::endl;
|
||||||
dout << tx.n_encoded_bits << std::endl;
|
dout << d_tx.n_encoded_bits << std::endl;
|
||||||
|
|
||||||
vec rx_signal(deinter, tx.n_encoded_bits);
|
vec rx_signal(deinter, d_tx.n_encoded_bits);
|
||||||
|
|
||||||
code.reset();
|
code.reset();
|
||||||
decoded_bits.set_length(tx.n_encoded_bits);
|
decoded_bits.set_length(d_tx.n_encoded_bits);
|
||||||
code.decode_tail(rx_signal, decoded_bits);
|
code.decode_tail(rx_signal, decoded_bits);
|
||||||
|
|
||||||
//dout << "length decoded " << decoded_bits.size() << std::endl;
|
//dout << "length decoded " << decoded_bits.size() << std::endl;
|
||||||
@@ -300,12 +310,14 @@ private:
|
|||||||
double deinter[1000 * 48];
|
double deinter[1000 * 48];
|
||||||
char out_bits[40000];
|
char out_bits[40000];
|
||||||
char out_bytes[40000];
|
char out_bytes[40000];
|
||||||
bvec decoded_bits;
|
bvec decoded_bits;
|
||||||
bool d_debug;
|
|
||||||
bool d_log;
|
bool d_debug;
|
||||||
tx_param tx;
|
bool d_log;
|
||||||
ofdm_param ofdm;
|
tx_param d_tx;
|
||||||
|
ofdm_param d_ofdm;
|
||||||
int copied;
|
int copied;
|
||||||
|
bool d_frame_complete;
|
||||||
|
|
||||||
Modulator<std::complex<double> > bpsk;
|
Modulator<std::complex<double> > bpsk;
|
||||||
Modulator<std::complex<double> > qpsk;
|
Modulator<std::complex<double> > qpsk;
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
#include <ieee802-11/ofdm_equalize_symbols.h>
|
#include <ieee802-11/ofdm_equalize_symbols.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "equalizer/base.h"
|
||||||
|
#include "equalizer/linear_comb.h"
|
||||||
|
#include "equalizer/lms.h"
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
@@ -25,12 +28,14 @@ using namespace gr::ieee802_11;
|
|||||||
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
|
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_equalize_symbols_impl(bool debug) : block("ofdm_equalize_symbols",
|
ofdm_equalize_symbols_impl(Equalizer algo, bool debug) : block("ofdm_equalize_symbols",
|
||||||
gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)),
|
||||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
||||||
d_debug(debug) {
|
d_debug(debug), d_equalizer(NULL) {
|
||||||
|
|
||||||
set_relative_rate(1);
|
set_relative_rate(1);
|
||||||
|
set_tag_propagation_policy(block::TPP_DONT);
|
||||||
|
set_algorithm(algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ofdm_equalize_symbols_impl(){
|
~ofdm_equalize_symbols_impl(){
|
||||||
@@ -40,86 +45,76 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
gr_vector_const_void_star& input_items,
|
gr_vector_const_void_star& input_items,
|
||||||
gr_vector_void_star& output_items) {
|
gr_vector_void_star& output_items) {
|
||||||
|
|
||||||
|
gr::thread::scoped_lock lock(d_mutex);
|
||||||
|
|
||||||
const gr_complex *in = (const gr_complex*)input_items[0];
|
const gr_complex *in = (const gr_complex*)input_items[0];
|
||||||
gr_complex *out = (gr_complex*)output_items[0];
|
gr_complex *out = (gr_complex*)output_items[0];
|
||||||
|
|
||||||
int noutput = noutput_items;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
int o = 0;
|
||||||
std::vector<gr::tag_t> tags;
|
|
||||||
const uint64_t nread = nitems_read(0);
|
|
||||||
|
|
||||||
dout << "SYMBOLS: input " << ninput_items[0] << " output " << noutput_items << std::endl;
|
dout << "SYMBOLS: input " << ninput_items[0] << " output " << noutput_items << std::endl;
|
||||||
|
|
||||||
while((i < ninput_items[0]) && (i < noutput)) {
|
while((i < ninput_items[0]) && (o < noutput_items)) {
|
||||||
|
|
||||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("ofdm_start"));
|
||||||
pmt::string_to_symbol("ofdm_start"));
|
|
||||||
|
|
||||||
|
// new WiFi frame
|
||||||
if(tags.size()) {
|
if(tags.size()) {
|
||||||
index = 0;
|
d_nsym = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gr_complex p = POLARITY[index];
|
// first data symbol (= signal field)
|
||||||
index++;
|
if(d_nsym == 2) {
|
||||||
|
add_item_tag(0, nitems_written(0) + o,
|
||||||
// FIXME: think about this... average over amplitude or power
|
pmt::string_to_symbol("ofdm_start"),
|
||||||
double avg_mag = (abs(in[11]) + abs(in[25]) + abs(in[39]) + abs(in[53])) / 4;
|
pmt::PMT_T,
|
||||||
|
pmt::string_to_symbol(name()));
|
||||||
|
|
||||||
double p1 = arg( p * in[11]);
|
|
||||||
double p2 = arg( p * in[25] * conj(p * in[11])) + p1;
|
|
||||||
double p3 = arg( p * in[39] * conj(p * in[25])) + p2;
|
|
||||||
double p4 = arg(-p * in[53] * conj(p * in[39])) + p3;
|
|
||||||
|
|
||||||
double my = (p1 + p2 + p3 + p4) / 4;
|
|
||||||
double mx = (11.0 + 25 + 39 + 53) / 4;
|
|
||||||
|
|
||||||
double var = (((11.0 * 11.0) + (25.0 * 25.0) + (39.0 * 39.0) + (53.0 * 53.0)) / 4) - (mx * mx);
|
|
||||||
double cov = (( (p1 * 11) + (p2 * 25) + (p3 * 39) + (p4 * 53) ) / 4) - (mx * my);
|
|
||||||
double beta = cov / var;
|
|
||||||
double alpha = my - beta * mx;
|
|
||||||
|
|
||||||
int o = 0;
|
|
||||||
for(int n = 0; n < 64; n++) {
|
|
||||||
if( (n == 11) || (n == 25) || (n == 32) || (n == 39) || (n == 53) || (n < 6) || ( n > 58)) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// FIXME: think about this... square or not
|
|
||||||
out[o] = in[n] * exp(gr_complex(0, -n * beta - alpha)) * gr_complex(1 / avg_mag, 0);
|
|
||||||
o++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d_equalizer->equalize(in + (i * 64), out + (o * 48), d_nsym);
|
||||||
|
|
||||||
|
if(d_nsym > 1) {
|
||||||
|
o++;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
in += 64;
|
d_nsym++;
|
||||||
out += 48;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dout << "SYMBOLS: produced / consumed " << i << std::endl;
|
dout << "SYMBOLS: consumed " << i << " produced " << o << std::endl;
|
||||||
|
|
||||||
consume(0, i);
|
consume(0, i);
|
||||||
return i;
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_algorithm(Equalizer algo) {
|
||||||
|
gr::thread::scoped_lock lock(d_mutex);
|
||||||
|
delete d_equalizer;
|
||||||
|
|
||||||
|
switch(algo) {
|
||||||
|
case LMS:
|
||||||
|
dout << "LMS" << std::endl;
|
||||||
|
d_equalizer = new equalizer::lms();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LINEAR_COMB:
|
||||||
|
dout << "Linear Comb" << std::endl;
|
||||||
|
d_equalizer = new equalizer::linear_comb();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int index;
|
int d_nsym;
|
||||||
const bool d_debug;
|
const bool d_debug;
|
||||||
static const gr_complex POLARITY[127];
|
equalizer::base *d_equalizer;
|
||||||
|
std::vector<gr::tag_t> tags;
|
||||||
|
gr::thread::mutex d_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
const gr_complex ofdm_equalize_symbols_impl::POLARITY[127] = {
|
|
||||||
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
|
|
||||||
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
|
|
||||||
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
|
|
||||||
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
|
|
||||||
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
|
|
||||||
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
|
|
||||||
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
|
|
||||||
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
|
|
||||||
|
|
||||||
ofdm_equalize_symbols::sptr
|
ofdm_equalize_symbols::sptr
|
||||||
ofdm_equalize_symbols::make(bool debug) {
|
ofdm_equalize_symbols::make(Equalizer algo, bool debug) {
|
||||||
return gnuradio::get_initial_sptr(new ofdm_equalize_symbols_impl(debug));
|
return gnuradio::get_initial_sptr(new ofdm_equalize_symbols_impl(algo, debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <ieee802-11/ofdm_freq_est.h>
|
|
||||||
#include "utils.h"
|
|
||||||
#include <gnuradio/io_signature.h>
|
|
||||||
|
|
||||||
using namespace gr::ieee802_11;
|
|
||||||
|
|
||||||
|
|
||||||
class ofdm_freq_est_impl : public ofdm_freq_est {
|
|
||||||
|
|
||||||
public:
|
|
||||||
ofdm_freq_est_impl(bool log, bool debug) : block("ofdm_freq_est",
|
|
||||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
|
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
|
||||||
d_log(log),
|
|
||||||
d_debug(debug),
|
|
||||||
d_state(SYNC) {
|
|
||||||
|
|
||||||
set_tag_propagation_policy(block::TPP_DONT);
|
|
||||||
}
|
|
||||||
|
|
||||||
int general_work (int noutput, gr_vector_int& ninput_items,
|
|
||||||
gr_vector_const_void_star& input_items,
|
|
||||||
gr_vector_void_star& output_items) {
|
|
||||||
|
|
||||||
const gr_complex *in = (const gr_complex*)input_items[0];
|
|
||||||
gr_complex *out = (gr_complex*)output_items[0];
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required) {
|
|
||||||
ninput_items_required[0] = noutput_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum {SYNC, COPY, RESET} d_state;
|
|
||||||
std::vector<gr::tag_t> d_tags;
|
|
||||||
|
|
||||||
const bool d_log;
|
|
||||||
const bool d_debug;
|
|
||||||
};
|
|
||||||
|
|
||||||
ofdm_freq_est::sptr
|
|
||||||
ofdm_freq_est::make(bool log, bool debug) {
|
|
||||||
return gnuradio::get_initial_sptr(new ofdm_freq_est_impl(log, debug));
|
|
||||||
}
|
|
||||||
|
|
||||||
+26
-14
@@ -65,7 +65,18 @@ ofdm_mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::v
|
|||||||
}
|
}
|
||||||
|
|
||||||
void phy_in (pmt::pmt_t msg) {
|
void phy_in (pmt::pmt_t msg) {
|
||||||
message_port_pub(pmt::mp("app out"), msg);
|
// this must be a pair
|
||||||
|
if (!pmt::is_blob(pmt::cdr(msg)))
|
||||||
|
throw std::runtime_error("PMT must be blob");
|
||||||
|
|
||||||
|
// strip MAC header
|
||||||
|
// TODO: check for frame type to determine header size
|
||||||
|
pmt::pmt_t blob(pmt::cdr(msg));
|
||||||
|
const char *mpdu = reinterpret_cast<const char *>(pmt::blob_data(blob));
|
||||||
|
std::cout << "pdu len " << pmt::blob_length(blob) << std::endl;
|
||||||
|
pmt::pmt_t msdu = pmt::make_blob(mpdu + 24, pmt::blob_length(blob) - 24);
|
||||||
|
|
||||||
|
message_port_pub(pmt::mp("app out"), pmt::cons(pmt::car(msg), msdu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_in (pmt::pmt_t msg) {
|
void app_in (pmt::pmt_t msg) {
|
||||||
@@ -99,10 +110,13 @@ void app_in (pmt::pmt_t msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(msg_len > 1500) {
|
||||||
|
throw std::invalid_argument("Frame too large (> 1500)");
|
||||||
|
}
|
||||||
|
|
||||||
// make MAC frame
|
// make MAC frame
|
||||||
int psdu_length;
|
int psdu_length;
|
||||||
char *psdu;
|
generate_mac_data_frame(msdu, msg_len, &psdu_length);
|
||||||
generate_mac_data_frame(msdu, msg_len, &psdu, &psdu_length);
|
|
||||||
|
|
||||||
dict = pmt::dict_add(dict, pmt::mp("crc_included"), pmt::PMT_T);
|
dict = pmt::dict_add(dict, pmt::mp("crc_included"), pmt::PMT_T);
|
||||||
|
|
||||||
@@ -120,20 +134,18 @@ void app_in (pmt::pmt_t msg) {
|
|||||||
|
|
||||||
|
|
||||||
// blob
|
// blob
|
||||||
pmt::pmt_t mac = pmt::make_blob(psdu, psdu_length);
|
pmt::pmt_t mac = pmt::make_blob(d_psdu, psdu_length);
|
||||||
|
|
||||||
// pdu
|
// pdu
|
||||||
message_port_pub(pmt::mp("phy out"), pmt::cons(dict, mac));
|
message_port_pub(pmt::mp("phy out"), pmt::cons(dict, mac));
|
||||||
|
|
||||||
free(psdu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_mac_data_frame(const char *msdu, int msdu_size, char **psdu, int *psdu_size) {
|
void generate_mac_data_frame(const char *msdu, int msdu_size, int *psdu_size) {
|
||||||
|
|
||||||
// mac header
|
// mac header
|
||||||
mac_header header;
|
mac_header header;
|
||||||
header.frame_control = 0x0008;
|
header.frame_control = 0x0008;
|
||||||
header.duration = 0x002e;
|
header.duration = 0x0000;
|
||||||
|
|
||||||
for(int i = 0; i < 6; i++) {
|
for(int i = 0; i < 6; i++) {
|
||||||
header.addr1[i] = d_dst_mac[i];
|
header.addr1[i] = d_dst_mac[i];
|
||||||
@@ -152,18 +164,17 @@ void generate_mac_data_frame(const char *msdu, int msdu_size, char **psdu, int *
|
|||||||
|
|
||||||
//header size is 24, plus 4 for FCS means 28 bytes
|
//header size is 24, plus 4 for FCS means 28 bytes
|
||||||
*psdu_size = 28 + msdu_size;
|
*psdu_size = 28 + msdu_size;
|
||||||
*psdu = (char *) calloc(*psdu_size, sizeof(char));
|
|
||||||
|
|
||||||
//copy mac header into psdu
|
//copy mac header into psdu
|
||||||
std::memcpy(*psdu, &header, 24);
|
std::memcpy(d_psdu, &header, 24);
|
||||||
//copy msdu into psdu
|
//copy msdu into psdu
|
||||||
memcpy(*psdu + 24, msdu, msdu_size);
|
memcpy(d_psdu + 24, msdu, msdu_size);
|
||||||
//compute and store fcs
|
//compute and store fcs
|
||||||
boost::crc_32_type result;
|
boost::crc_32_type result;
|
||||||
result.process_bytes(*psdu, msdu_size + 24);
|
result.process_bytes(d_psdu, msdu_size + 24);
|
||||||
|
|
||||||
unsigned int fcs = result.checksum();
|
uint32_t fcs = result.checksum();
|
||||||
memcpy(*psdu + msdu_size + 24, &fcs, sizeof(unsigned int));
|
memcpy(d_psdu + msdu_size + 24, &fcs, sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_mac(std::vector<uint8_t> mac) {
|
bool check_mac(std::vector<uint8_t> mac) {
|
||||||
@@ -176,6 +187,7 @@ private:
|
|||||||
uint8_t d_src_mac[6];
|
uint8_t d_src_mac[6];
|
||||||
uint8_t d_dst_mac[6];
|
uint8_t d_dst_mac[6];
|
||||||
uint8_t d_bss_mac[6];
|
uint8_t d_bss_mac[6];
|
||||||
|
uint8_t d_psdu[1528];
|
||||||
};
|
};
|
||||||
|
|
||||||
ofdm_mac::sptr
|
ofdm_mac::sptr
|
||||||
|
|||||||
+2
-2
@@ -82,8 +82,8 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
|||||||
|
|
||||||
// ############ INSERT MAC STUFF
|
// ############ INSERT MAC STUFF
|
||||||
tx_param tx(d_ofdm, psdu_length);
|
tx_param tx(d_ofdm, psdu_length);
|
||||||
if(tx.n_sym > 120) {
|
if(tx.n_sym > MAX_SYM) {
|
||||||
std::cout << "packet too large" <<std::endl;
|
std::cout << "packet too large, maximum number of symbols is " << MAX_SYM << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-9
@@ -31,11 +31,13 @@ ofdm_parse_mac_impl(bool log, bool debug) :
|
|||||||
block("ofdm_parse_mac",
|
block("ofdm_parse_mac",
|
||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
gr::io_signature::make(0, 0, 0)),
|
gr::io_signature::make(0, 0, 0)),
|
||||||
d_log(log),
|
d_log(log), d_last_seq_no(-1),
|
||||||
d_debug(debug) {
|
d_debug(debug) {
|
||||||
|
|
||||||
message_port_register_in(pmt::mp("in"));
|
message_port_register_in(pmt::mp("in"));
|
||||||
set_msg_handler(pmt::mp("in"), boost::bind(&ofdm_parse_mac_impl::parse, this, _1));
|
set_msg_handler(pmt::mp("in"), boost::bind(&ofdm_parse_mac_impl::parse, this, _1));
|
||||||
|
|
||||||
|
message_port_register_out(pmt::mp("fer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
~ofdm_parse_mac_impl() {
|
~ofdm_parse_mac_impl() {
|
||||||
@@ -89,10 +91,6 @@ void parse(pmt::pmt_t msg) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data_len < 32) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *frame = (char*)pmt::blob_data(msg);
|
char *frame = (char*)pmt::blob_data(msg);
|
||||||
|
|
||||||
// DATA
|
// DATA
|
||||||
@@ -251,13 +249,29 @@ void parse_data(char *buf, int length) {
|
|||||||
}
|
}
|
||||||
dout << std::endl;
|
dout << std::endl;
|
||||||
|
|
||||||
dout << "seq nr: " << int(h->seq_nr >> 4) << std::endl;
|
int seq_no = int(h->seq_nr >> 4);
|
||||||
|
dout << "seq nr: " << seq_no << std::endl;
|
||||||
dout << "mac 1: ";
|
dout << "mac 1: ";
|
||||||
print_mac_address(h->addr1, true);
|
print_mac_address(h->addr1, true);
|
||||||
dout << "mac 2: ";
|
dout << "mac 2: ";
|
||||||
print_mac_address(h->addr2, true);
|
print_mac_address(h->addr2, true);
|
||||||
dout << "mac 3: ";
|
dout << "mac 3: ";
|
||||||
print_mac_address(h->addr3, true);
|
print_mac_address(h->addr3, true);
|
||||||
|
|
||||||
|
float lost_frames = seq_no - d_last_seq_no - 1;
|
||||||
|
if(lost_frames < 0)
|
||||||
|
lost_frames += 1 << 12;
|
||||||
|
|
||||||
|
// calculate frame error rate
|
||||||
|
float fer = lost_frames / (lost_frames + 1);
|
||||||
|
dout << "instantaneous fer: " << fer << std::endl;
|
||||||
|
|
||||||
|
// keep track of values
|
||||||
|
d_last_seq_no = seq_no;
|
||||||
|
|
||||||
|
// publish FER estimate
|
||||||
|
pmt::pmt_t pdu = pmt::make_f32vector(lost_frames + 1, fer * 100);
|
||||||
|
message_port_pub(pmt::mp("fer"), pmt::cons( pmt::PMT_NIL, pdu ));
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_control(char *buf, int length) {
|
void parse_control(char *buf, int length) {
|
||||||
@@ -341,7 +355,7 @@ void print_ascii(char* buf, int length) {
|
|||||||
private:
|
private:
|
||||||
bool d_log;
|
bool d_log;
|
||||||
bool d_debug;
|
bool d_debug;
|
||||||
|
int d_last_seq_no;
|
||||||
};
|
};
|
||||||
|
|
||||||
ofdm_parse_mac::sptr
|
ofdm_parse_mac::sptr
|
||||||
|
|||||||
+56
-53
@@ -27,29 +27,29 @@ using namespace gr::ieee802_11;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
bool compare_abs(const std::pair<gr_complex, int>& first, const std::pair<gr_complex, int>& second) {
|
||||||
|
return abs(get<0>(first)) > abs(get<0>(second));
|
||||||
|
}
|
||||||
|
|
||||||
class ofdm_sync_long_impl : public ofdm_sync_long {
|
class ofdm_sync_long_impl : public ofdm_sync_long {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("ofdm_sync_long",
|
ofdm_sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("ofdm_sync_long",
|
||||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
|
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||||
|
d_fir(gr::filter::kernel::fir_filter_ccc(1, LONG)),
|
||||||
d_log(log),
|
d_log(log),
|
||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
d_offset(0),
|
d_offset(0),
|
||||||
d_freq_est(0),
|
|
||||||
d_state(SYNC),
|
d_state(SYNC),
|
||||||
SYNC_LENGTH(sync_length) {
|
SYNC_LENGTH(sync_length) {
|
||||||
|
|
||||||
set_tag_propagation_policy(block::TPP_DONT);
|
set_tag_propagation_policy(block::TPP_DONT);
|
||||||
d_fir = new gr::filter::kernel::fir_filter_ccc(1, LONG);
|
|
||||||
d_correlation = gr::fft::malloc_complex(8192);
|
d_correlation = gr::fft::malloc_complex(8192);
|
||||||
d_freq_est_buf = static_cast<gr_complex*>(std::malloc(sync_length * sizeof(gr_complex)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~ofdm_sync_long_impl(){
|
~ofdm_sync_long_impl(){
|
||||||
delete d_fir;
|
|
||||||
gr::fft::free(d_correlation);
|
gr::fft::free(d_correlation);
|
||||||
free(d_freq_est_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int general_work (int noutput, gr_vector_int& ninput_items,
|
int general_work (int noutput, gr_vector_int& ninput_items,
|
||||||
@@ -64,19 +64,21 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
ninput_items[1] << " noutput " << noutput <<
|
ninput_items[1] << " noutput " << noutput <<
|
||||||
" state " << d_state << std::endl;
|
" state " << d_state << std::endl;
|
||||||
|
|
||||||
int ninput = std::min(ninput_items[0], ninput_items[1]);
|
int ninput = std::min(std::min(ninput_items[0], ninput_items[1]), 8192);
|
||||||
|
|
||||||
const unsigned int nread = nitems_read(0);
|
const unsigned int nread = nitems_read(0);
|
||||||
get_tags_in_range(d_tags, 0, nread, nread + ninput);
|
get_tags_in_range(d_tags, 0, nread, nread + ninput);
|
||||||
if (d_tags.size()) {
|
if (d_tags.size()) {
|
||||||
std::sort(d_tags.begin(), d_tags.end(), gr::tag_t::offset_compare);
|
std::sort(d_tags.begin(), d_tags.end(), gr::tag_t::offset_compare);
|
||||||
|
|
||||||
const gr::tag_t &tag = d_tags.front();
|
const uint64_t offset = d_tags.front().offset;
|
||||||
const uint64_t offset = tag.offset;
|
|
||||||
|
|
||||||
if(offset > nread) {
|
if(offset > nread) {
|
||||||
ninput = offset - nread;
|
ninput = offset - nread;
|
||||||
} else {
|
} else {
|
||||||
|
if(d_offset && (d_state == SYNC)) {
|
||||||
|
throw std::runtime_error("wtf");
|
||||||
|
}
|
||||||
if(d_state == COPY) {
|
if(d_state == COPY) {
|
||||||
d_state = RESET;
|
d_state = RESET;
|
||||||
}
|
}
|
||||||
@@ -90,26 +92,20 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
switch(d_state) {
|
switch(d_state) {
|
||||||
|
|
||||||
case SYNC:
|
case SYNC:
|
||||||
d_fir->filterN(d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - 63, 0)));
|
d_fir.filterN(d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - 63, 0)));
|
||||||
|
|
||||||
while(i + 63 < ninput) {
|
while(i + 63 < ninput) {
|
||||||
|
|
||||||
d_freq_est += in[i] * conj(in[i + 16]);
|
d_cor.push_back(pair<gr_complex, int>(d_correlation[i], d_offset));
|
||||||
d_freq_est_buf[d_offset] = d_freq_est;
|
|
||||||
|
|
||||||
d_cor.push_back(pair<double, int>(abs(d_correlation[i]), d_offset));
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
d_offset++;
|
d_offset++;
|
||||||
|
|
||||||
if(d_offset == SYNC_LENGTH) {
|
if(d_offset == SYNC_LENGTH) {
|
||||||
search_frame_start();
|
search_frame_start();
|
||||||
d_freq_est = d_freq_est_buf[std::max<int>(0, d_frame_start - 160 - 17)];
|
|
||||||
d_offset = 0;
|
d_offset = 0;
|
||||||
d_state = COPY;
|
d_state = COPY;
|
||||||
|
|
||||||
mylog(boost::format("frame at %1% - freq_est (20M): %2%") % d_frame_start
|
|
||||||
% ((arg(d_freq_est) / 16) * 20e6 / (2 * M_PI)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,59 +113,53 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case COPY:
|
case COPY:
|
||||||
while(i < ninput) {
|
while(i < ninput && o < noutput) {
|
||||||
|
|
||||||
int rel = d_offset - d_frame_start;
|
int rel = d_offset - d_frame_start;
|
||||||
if( (rel >= 0) && (rel % 80 > 15)) {
|
|
||||||
|
|
||||||
if(o >= noutput) {
|
if(!rel) {
|
||||||
break;
|
add_item_tag(0, nitems_written(0),
|
||||||
}
|
pmt::string_to_symbol("ofdm_start"),
|
||||||
|
pmt::PMT_T,
|
||||||
|
pmt::string_to_symbol(name()));
|
||||||
|
}
|
||||||
|
|
||||||
if(rel == 16) {
|
if(rel >= 0 && (rel < 128 || ((rel - 128) % 80) > 15)) {
|
||||||
assert(o == 0);
|
out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset));
|
||||||
add_item_tag(0, nitems_written(0) + o,
|
|
||||||
pmt::string_to_symbol("ofdm_start"),
|
|
||||||
pmt::PMT_T,
|
|
||||||
pmt::string_to_symbol(name()));
|
|
||||||
}
|
|
||||||
|
|
||||||
out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * arg(d_freq_est) / 16));
|
|
||||||
o++;
|
o++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
d_offset++;
|
d_offset++;
|
||||||
|
if(d_offset == 1) {
|
||||||
|
dout << "produced " << d_count << " " << d_count / 64.0 << std::endl;
|
||||||
|
d_count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESET:
|
case RESET: {
|
||||||
|
int h = 0;
|
||||||
while(o < noutput) {
|
while(o < noutput) {
|
||||||
int rel = (d_offset - d_frame_start) % 80;
|
if(((d_count + h) % 64) == 0) {
|
||||||
|
|
||||||
if(!rel) {
|
|
||||||
d_offset = 0;
|
d_offset = 0;
|
||||||
d_freq_est = gr_complex(0, 0);
|
|
||||||
d_state = SYNC;
|
d_state = SYNC;
|
||||||
break;
|
break;
|
||||||
} else if(rel > 15) {
|
} else {
|
||||||
out[o] = 0;
|
out[o] = 0;
|
||||||
o++;
|
o++;
|
||||||
}
|
}
|
||||||
d_offset++;
|
h++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
|
||||||
std::runtime_error("bad state");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dout << "produced : " << o << " consumed: " << i << std::endl;
|
dout << "produced : " << o << " consumed: " << i << std::endl;
|
||||||
|
|
||||||
|
d_count += o;
|
||||||
consume(0, i);
|
consume(0, i);
|
||||||
consume(1, i);
|
consume(1, i);
|
||||||
return o;
|
return o;
|
||||||
@@ -193,11 +183,10 @@ void search_frame_start() {
|
|||||||
|
|
||||||
// sort list (highest correlation first)
|
// sort list (highest correlation first)
|
||||||
assert(d_cor.size() == SYNC_LENGTH);
|
assert(d_cor.size() == SYNC_LENGTH);
|
||||||
d_cor.sort();
|
d_cor.sort(compare_abs);
|
||||||
d_cor.reverse();
|
|
||||||
|
|
||||||
// copy list in vector for nicer access
|
// copy list in vector for nicer access
|
||||||
vector<pair<double, int> > vec(d_cor.begin(), d_cor.end());
|
vector<pair<gr_complex, int> > vec(d_cor.begin(), d_cor.end());
|
||||||
d_cor.clear();
|
d_cor.clear();
|
||||||
|
|
||||||
// in case we don't find anything use SYNC_LENGTH
|
// in case we don't find anything use SYNC_LENGTH
|
||||||
@@ -205,17 +194,30 @@ void search_frame_start() {
|
|||||||
|
|
||||||
for(int i = 0; i < 3; i++) {
|
for(int i = 0; i < 3; i++) {
|
||||||
for(int k = i + 1; k < 4; k++) {
|
for(int k = i + 1; k < 4; k++) {
|
||||||
int diff = abs(get<1>(vec[i]) - get<1>(vec[k]));
|
gr_complex first;
|
||||||
|
gr_complex second;
|
||||||
|
if(get<1>(vec[i]) > get<1>(vec[k])) {
|
||||||
|
first = get<0>(vec[k]);
|
||||||
|
second = get<0>(vec[i]);
|
||||||
|
} else {
|
||||||
|
first = get<0>(vec[i]);
|
||||||
|
second = get<0>(vec[k]);
|
||||||
|
}
|
||||||
|
int diff = abs(get<1>(vec[i]) - get<1>(vec[k]));
|
||||||
if(diff == 64) {
|
if(diff == 64) {
|
||||||
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64;
|
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64 - 128 - 1;
|
||||||
|
d_freq_offset = arg(first * conj(second)) / 64;
|
||||||
|
//std::cout << "frequency offset " << d_freq_offset << std::endl;
|
||||||
// nice match found, return immediately
|
// nice match found, return immediately
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: check if these offsets make sense
|
// TODO: check if these offsets make sense
|
||||||
} else if(diff == 63) {
|
} else if(diff == 63) {
|
||||||
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 63;
|
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 63 - 128 - 1;
|
||||||
|
d_freq_offset = arg(first * conj(second)) / 64;
|
||||||
} else if(diff == 65) {
|
} else if(diff == 65) {
|
||||||
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64;
|
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64 - 128 - 1;
|
||||||
|
d_freq_offset = arg(first * conj(second)) / 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,14 +225,15 @@ void search_frame_start() {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum {SYNC, COPY, RESET} d_state;
|
enum {SYNC, COPY, RESET} d_state;
|
||||||
|
int d_count;
|
||||||
int d_offset;
|
int d_offset;
|
||||||
int d_frame_start;
|
int d_frame_start;
|
||||||
gr_complex d_freq_est;
|
float d_freq_offset;
|
||||||
|
|
||||||
gr_complex *d_correlation;
|
gr_complex *d_correlation;
|
||||||
gr_complex *d_freq_est_buf;
|
list<pair<gr_complex, int> > d_cor;
|
||||||
list<pair<double, int> > d_cor;
|
|
||||||
std::vector<gr::tag_t> d_tags;
|
std::vector<gr::tag_t> d_tags;
|
||||||
gr::filter::kernel::fir_filter_ccc *d_fir;
|
gr::filter::kernel::fir_filter_ccc d_fir;
|
||||||
|
|
||||||
const bool d_log;
|
const bool d_log;
|
||||||
const bool d_debug;
|
const bool d_debug;
|
||||||
|
|||||||
+52
-33
@@ -22,37 +22,39 @@
|
|||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
static const int MIN_GAP = 480;
|
||||||
|
static const int MAX_SAMPLES = 540 * 80;
|
||||||
|
|
||||||
class ofdm_sync_short_impl : public ofdm_sync_short {
|
class ofdm_sync_short_impl : public ofdm_sync_short {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_sync_short_impl(double threshold, unsigned int max_samples,
|
ofdm_sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) :
|
||||||
unsigned int min_plateau, bool log, bool debug) : block("ofdm_sync_short",
|
block("ofdm_sync_short",
|
||||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(float)),
|
gr::io_signature::make3(3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)),
|
||||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||||
d_log(log),
|
d_log(log),
|
||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
d_state(SEARCH),
|
d_state(SEARCH),
|
||||||
d_plateau(0),
|
d_plateau(0),
|
||||||
MAX_SAMPLES(max_samples),
|
d_freq_offset(0),
|
||||||
MIN_PLATEAU(min_plateau),
|
d_copied(0),
|
||||||
d_threshold(threshold) {
|
MIN_PLATEAU(min_plateau),
|
||||||
|
d_threshold(threshold) {
|
||||||
|
|
||||||
set_tag_propagation_policy(block::TPP_DONT);
|
set_tag_propagation_policy(block::TPP_DONT);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ofdm_sync_short_impl(){
|
|
||||||
}
|
|
||||||
|
|
||||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||||
gr_vector_const_void_star& input_items,
|
gr_vector_const_void_star& input_items,
|
||||||
gr_vector_void_star& output_items) {
|
gr_vector_void_star& output_items) {
|
||||||
|
|
||||||
const gr_complex *in = (const gr_complex*)input_items[0];
|
const gr_complex *in = (const gr_complex*)input_items[0];
|
||||||
const float *in2 = (const float*)input_items[1];
|
const gr_complex *in_abs = (const gr_complex*)input_items[1];
|
||||||
|
const float *in_cor = (const float*)input_items[2];
|
||||||
gr_complex *out = (gr_complex*)output_items[0];
|
gr_complex *out = (gr_complex*)output_items[0];
|
||||||
|
|
||||||
int noutput = noutput_items;
|
int noutput = noutput_items;
|
||||||
int ninput = std::min(ninput_items[0], ninput_items[1]);
|
int ninput = std::min(std::min(ninput_items[0], ninput_items[1]), ninput_items[2]);
|
||||||
|
|
||||||
// dout << "SHORT noutput : " << noutput << " ninput: " << ninput_items[0] << std::endl;
|
// dout << "SHORT noutput : " << noutput << " ninput: " << ninput_items[0] << std::endl;
|
||||||
|
|
||||||
@@ -62,13 +64,14 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < ninput; i++) {
|
for(i = 0; i < ninput; i++) {
|
||||||
if(in2[i] > d_threshold) {
|
if(in_cor[i] > d_threshold) {
|
||||||
if(d_plateau < MIN_PLATEAU) {
|
if(d_plateau < MIN_PLATEAU) {
|
||||||
d_plateau++;
|
d_plateau++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
d_state = COPY;
|
d_state = COPY;
|
||||||
d_copy_left = MAX_SAMPLES;
|
d_copied = 0;
|
||||||
|
d_freq_offset = arg(in_abs[i]) / 16;
|
||||||
d_plateau = 0;
|
d_plateau = 0;
|
||||||
insert_tag(nitems_written(0));
|
insert_tag(nitems_written(0));
|
||||||
dout << "SHORT Frame!" << std::endl;
|
dout << "SHORT Frame!" << std::endl;
|
||||||
@@ -79,27 +82,45 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(0, i);
|
consume_each(i);
|
||||||
consume(1, i);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case COPY: {
|
case COPY: {
|
||||||
|
|
||||||
int to_copy = std::min(d_copy_left, std::min(noutput, ninput));
|
int o = 0;
|
||||||
std::memcpy(out, in, to_copy * sizeof(gr_complex));
|
while( o < ninput && o < noutput && d_copied < MAX_SAMPLES) {
|
||||||
|
if(in_cor[o] > d_threshold) {
|
||||||
|
if(d_plateau < MIN_PLATEAU) {
|
||||||
|
d_plateau++;
|
||||||
|
|
||||||
d_copy_left -= to_copy;
|
// there's another frame
|
||||||
|
} else if(d_copied > MIN_GAP) {
|
||||||
|
d_copied = 0;
|
||||||
|
d_plateau = 0;
|
||||||
|
d_freq_offset = arg(in_abs[o]) / 16;
|
||||||
|
insert_tag(nitems_written(0) + o);
|
||||||
|
dout << "SHORT Frame!" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(!d_copy_left) {
|
} else {
|
||||||
|
d_plateau = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out[o] = in[o] * exp(gr_complex(0, -d_freq_offset * d_copied));
|
||||||
|
o++;
|
||||||
|
d_copied++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(d_copied == MAX_SAMPLES) {
|
||||||
d_state = SEARCH;
|
d_state = SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
dout << "SHORT copied " << to_copy << std::endl;
|
dout << "SHORT copied " << o << std::endl;
|
||||||
|
|
||||||
consume(0, to_copy);
|
consume_each(o);
|
||||||
consume(1, to_copy);
|
return o;
|
||||||
return to_copy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,18 +139,16 @@ void insert_tag(uint64_t item) {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum {SEARCH, COPY} d_state;
|
enum {SEARCH, COPY} d_state;
|
||||||
int d_copy_left;
|
int d_copied;
|
||||||
int d_plateau;
|
int d_plateau;
|
||||||
|
float d_freq_offset;
|
||||||
const double d_threshold;
|
const double d_threshold;
|
||||||
const bool d_log;
|
const bool d_log;
|
||||||
const bool d_debug;
|
const bool d_debug;
|
||||||
const unsigned int MAX_SAMPLES;
|
|
||||||
const unsigned int MIN_PLATEAU;
|
const unsigned int MIN_PLATEAU;
|
||||||
};
|
};
|
||||||
|
|
||||||
ofdm_sync_short::sptr
|
ofdm_sync_short::sptr
|
||||||
ofdm_sync_short::make(double threshold, unsigned int max_samples,
|
ofdm_sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) {
|
||||||
unsigned int min_plateau, bool log, bool debug) {
|
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold, min_plateau, log, debug));
|
||||||
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold,
|
|
||||||
max_samples, min_plateau, log, debug));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
const int MAX_SYM = 520; // enough for 1500 byte BPSK 1/2
|
||||||
|
const int MAX_BITS = 1550 * 8 * 2;
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
#define dout d_debug && std::cout
|
||||||
|
|
||||||
#if defined(HAVE_LOG4CPP) && defined(ENABLE_GR_LOG)
|
#if defined(HAVE_LOG4CPP) && defined(ENABLE_GR_LOG)
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
#include "ieee802-11/ofdm_decode_mac.h"
|
#include "ieee802-11/ofdm_decode_mac.h"
|
||||||
#include "ieee802-11/ofdm_decode_signal.h"
|
#include "ieee802-11/ofdm_decode_signal.h"
|
||||||
#include "ieee802-11/ofdm_equalize_symbols.h"
|
#include "ieee802-11/ofdm_equalize_symbols.h"
|
||||||
#include "ieee802-11/ofdm_freq_est.h"
|
|
||||||
#include "ieee802-11/ofdm_mac.h"
|
#include "ieee802-11/ofdm_mac.h"
|
||||||
#include "ieee802-11/ofdm_mapper.h"
|
#include "ieee802-11/ofdm_mapper.h"
|
||||||
#include "ieee802-11/ofdm_parse_mac.h"
|
#include "ieee802-11/ofdm_parse_mac.h"
|
||||||
@@ -51,7 +50,6 @@
|
|||||||
%include "ieee802-11/ofdm_decode_mac.h"
|
%include "ieee802-11/ofdm_decode_mac.h"
|
||||||
%include "ieee802-11/ofdm_decode_signal.h"
|
%include "ieee802-11/ofdm_decode_signal.h"
|
||||||
%include "ieee802-11/ofdm_equalize_symbols.h"
|
%include "ieee802-11/ofdm_equalize_symbols.h"
|
||||||
%include "ieee802-11/ofdm_freq_est.h"
|
|
||||||
%include "ieee802-11/ofdm_mac.h"
|
%include "ieee802-11/ofdm_mac.h"
|
||||||
%include "ieee802-11/ofdm_mapper.h"
|
%include "ieee802-11/ofdm_mapper.h"
|
||||||
%include "ieee802-11/ofdm_parse_mac.h"
|
%include "ieee802-11/ofdm_parse_mac.h"
|
||||||
@@ -68,7 +66,6 @@ GR_SWIG_BLOCK_MAGIC2(ieee802_11, moving_average_ff);
|
|||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_mac);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_mac);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_signal);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_decode_signal);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_equalize_symbols);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_equalize_symbols);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_freq_est);
|
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_mac);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_mac);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_mapper);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_mapper);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_parse_mac);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_parse_mac);
|
||||||
|
|||||||
Reference in New Issue
Block a user