code changes
This commit is contained in:
@@ -14,20 +14,75 @@
|
|||||||
# 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/>.
|
||||||
#
|
#
|
||||||
|
include(GrPython)
|
||||||
|
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
|
||||||
|
#!${PYTHON_EXECUTABLE}
|
||||||
|
|
||||||
|
import sys, os, re
|
||||||
|
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
|
||||||
|
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
|
||||||
|
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.path.append('${CMAKE_CURRENT_SOURCE_DIR}/../../python')
|
||||||
|
import build_utils
|
||||||
|
root, inp = sys.argv[1:3]
|
||||||
|
for sig in sys.argv[3:]:
|
||||||
|
name = re.sub ('X+', sig, root)
|
||||||
|
d = build_utils.standard_dict(name, sig, 'ieee802_11')
|
||||||
|
build_utils.expand_template(d, inp)
|
||||||
|
|
||||||
|
")
|
||||||
|
|
||||||
|
macro(expand_h root)
|
||||||
|
#make a list of all the generated files
|
||||||
|
unset(expanded_files_h)
|
||||||
|
foreach(sig ${ARGN})
|
||||||
|
string(REGEX REPLACE "X+" ${sig} name ${root})
|
||||||
|
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
|
||||||
|
endforeach(sig)
|
||||||
|
|
||||||
|
#create a command to generate the files
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${expanded_files_h}
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
|
||||||
|
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||||
|
${root} ${root}.h.t ${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
#install rules for the generated h files
|
||||||
|
list(APPEND generated_includes ${expanded_files_h})
|
||||||
|
endmacro(expand_h)
|
||||||
|
|
||||||
|
expand_h(moving_average_XX ff cc)
|
||||||
|
|
||||||
|
add_custom_target(ieee802_11_generated_includes DEPENDS
|
||||||
|
${generated_includes}
|
||||||
|
)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Install public header files
|
# Install public header files
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
list(APPEND include_sources
|
list(APPEND include_sources
|
||||||
|
${generated_includes}
|
||||||
api.h
|
api.h
|
||||||
ether_encap.h
|
ether_encap.h
|
||||||
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_mapper.h
|
||||||
ofdm_parse_mac.h
|
ofdm_parse_mac.h
|
||||||
|
ofdm_pilot.h
|
||||||
|
ofdm_preamble.h
|
||||||
ofdm_sync_long.h
|
ofdm_sync_long.h
|
||||||
ofdm_sync_short.h
|
ofdm_sync_short.h
|
||||||
|
wave_llc.h
|
||||||
|
wave_short_message.h
|
||||||
)
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef @GUARD_NAME@
|
||||||
|
#define @GUARD_NAME@
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/sync_block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API @NAME@ : virtual public sync_block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<@NAME@> sptr;
|
||||||
|
static sptr make(int length);
|
||||||
|
|
||||||
|
virtual int length() const = 0;
|
||||||
|
virtual void set_length(int length) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace blocks */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
||||||
|
#endif /* @GUARD_NAME@ */
|
||||||
@@ -28,7 +28,7 @@ class IEEE802_11_API ofdm_decode_mac : virtual public block
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ofdm_decode_mac> sptr;
|
typedef boost::shared_ptr<ofdm_decode_mac> sptr;
|
||||||
static sptr make(bool debug = false);
|
static sptr make(bool log = false, bool debug = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class IEEE802_11_API ofdm_decode_signal : virtual public block
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ofdm_decode_signal> sptr;
|
typedef boost::shared_ptr<ofdm_decode_signal> sptr;
|
||||||
static sptr make(bool debug = false);
|
static sptr make(bool log = false, bool debug = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_OFDM_FREQ_EST_H
|
||||||
|
#define INCLUDED_IEEE802_11_OFDM_FREQ_EST_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API ofdm_freq_est : virtual public block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<ofdm_freq_est> sptr;
|
||||||
|
static sptr make(bool log = false, bool debug = false);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_OFDM_FREQ_EST_H */
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_OFDM_MAC_H
|
||||||
|
#define INCLUDED_IEEE802_11_OFDM_MAC_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API ofdm_mac : virtual public block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<ofdm_mac> sptr;
|
||||||
|
static sptr make();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_OFDM_MAC_H */
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_OFDM_MAPPER_H
|
||||||
|
#define INCLUDED_IEEE802_11_OFDM_MAPPER_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
enum Encoding {
|
||||||
|
BPSK_1_2 = 0,
|
||||||
|
BPSK_3_4 = 1,
|
||||||
|
QPSK_1_2 = 2,
|
||||||
|
QPSK_3_4 = 3,
|
||||||
|
QAM16_1_2 = 4,
|
||||||
|
QAM16_3_4 = 5,
|
||||||
|
QAM64_2_3 = 6,
|
||||||
|
QAM64_3_4 = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API ofdm_mapper : virtual public block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<ofdm_mapper> sptr;
|
||||||
|
static sptr make(Encoding mcs, bool debug = false);
|
||||||
|
virtual void set_encoding(Encoding mcs) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_OFDM_MAPPER_H */
|
||||||
@@ -28,7 +28,7 @@ class IEEE802_11_API ofdm_parse_mac : virtual public block
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ofdm_parse_mac> sptr;
|
typedef boost::shared_ptr<ofdm_parse_mac> sptr;
|
||||||
static sptr make(bool debug);
|
static sptr make(bool log = false, bool debug = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_PILOT_H
|
||||||
|
#define INCLUDED_IEEE802_11_PILOT_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/sync_block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API ofdm_pilot : virtual public sync_block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<ofdm_pilot> sptr;
|
||||||
|
static sptr make(bool debug = false);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_PILOT_H */
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_OFDM_PREAMBLE_H
|
||||||
|
#define INCLUDED_IEEE802_11_OFDM_PREAMBLE_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API ofdm_preamble : virtual public block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<ofdm_preamble> sptr;
|
||||||
|
static sptr make(bool debug = false);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_OFDM_PREAMBLE_H */
|
||||||
@@ -28,8 +28,8 @@ class IEEE802_11_API ofdm_sync_long : virtual public block
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef boost::shared_ptr<ofdm_sync_long> sptr;
|
typedef boost::shared_ptr<ofdm_sync_long> sptr;
|
||||||
static sptr make(unsigned int sync_length, unsigned int freq_est,
|
static sptr make(unsigned int sync_length,
|
||||||
bool debug = false);
|
bool log = false, bool debug = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ 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 max_samples,
|
||||||
unsigned int min_plateau, bool debug = false);
|
unsigned int min_plateau, bool log = false, bool debug = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_WAVE_LLC_H
|
||||||
|
#define INCLUDED_IEEE802_11_WAVE_LLC_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API wave_llc : virtual public block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<wave_llc> sptr;
|
||||||
|
static sptr make();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_WAVE_LLC_H */
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_WAVE_SHORT_MESSAGE_H
|
||||||
|
#define INCLUDED_IEEE802_11_WAVE_SHORT_MESSAGE_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class IEEE802_11_API wave_short_message : virtual public block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void set_version(int version) = 0;
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<wave_short_message> sptr;
|
||||||
|
static sptr make(int version);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_WAVE_SHORT_MESSAGE_H */
|
||||||
+89
-1
@@ -20,15 +20,102 @@
|
|||||||
########################################################################
|
########################################################################
|
||||||
include(GrPlatform) #define LIB_SUFFIX
|
include(GrPlatform) #define LIB_SUFFIX
|
||||||
|
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
|
||||||
|
#!${PYTHON_EXECUTABLE}
|
||||||
|
|
||||||
|
import sys, os, re
|
||||||
|
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
|
||||||
|
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
|
||||||
|
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.path.append('${CMAKE_CURRENT_SOURCE_DIR}/../python')
|
||||||
|
import build_utils
|
||||||
|
root, inp = sys.argv[1:3]
|
||||||
|
for sig in sys.argv[3:]:
|
||||||
|
name = re.sub ('X+', sig, root)
|
||||||
|
d = build_utils.standard_dict(name, sig, 'ieee802_11')
|
||||||
|
build_utils.expand_template(d, inp, '_impl')
|
||||||
|
")
|
||||||
|
|
||||||
|
|
||||||
|
macro(expand_cc_h_impl root)
|
||||||
|
#make a list of all the generated files
|
||||||
|
unset(expanded_files_cc_impl)
|
||||||
|
unset(expanded_files_h_impl)
|
||||||
|
foreach(sig ${ARGN})
|
||||||
|
string(REGEX REPLACE "X+" ${sig} name ${root})
|
||||||
|
list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
|
||||||
|
list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
|
||||||
|
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/${name}.h)
|
||||||
|
endforeach(sig)
|
||||||
|
|
||||||
|
#create a command to generate the _impl.cc files
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${expanded_files_cc_impl}
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
|
||||||
|
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||||
|
${root} ${root}_impl.cc.t ${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
#create a command to generate the _impl.h files
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${expanded_files_h_impl}
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
|
||||||
|
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
|
||||||
|
${root} ${root}_impl.h.t ${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
#make _impl.cc source files depend on headers to force generation
|
||||||
|
set_source_files_properties(${expanded_files_cc_impl}
|
||||||
|
PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
|
||||||
|
)
|
||||||
|
|
||||||
|
#make _impl.h source files depend on headers to force generation
|
||||||
|
set_source_files_properties(${expanded_files_h_impl}
|
||||||
|
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
|
||||||
|
)
|
||||||
|
|
||||||
|
#install rules for the generated cc files
|
||||||
|
list(APPEND generated_sources ${expanded_files_cc_impl})
|
||||||
|
endmacro(expand_cc_h_impl)
|
||||||
|
########################################################################
|
||||||
|
# Invoke macro to generate various sources
|
||||||
|
########################################################################
|
||||||
|
expand_cc_h_impl(moving_average_XX cc ff)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/../include
|
||||||
|
${GR_BLOCKS_INCLUDE_DIRS}
|
||||||
|
${GNURADIO_RUNTIME_INCLUDE_DIRS}
|
||||||
|
${VOLK_INCLUDE_DIRS}
|
||||||
|
${Boost_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Setup library
|
||||||
|
########################################################################
|
||||||
list(APPEND gr_ieee802_11_sources
|
list(APPEND gr_ieee802_11_sources
|
||||||
|
${generated_sources}
|
||||||
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_mapper.cc
|
||||||
ofdm_parse_mac.cc
|
ofdm_parse_mac.cc
|
||||||
|
ofdm_pilot.cc
|
||||||
|
ofdm_preamble.cc
|
||||||
ofdm_sync_long.cc
|
ofdm_sync_long.cc
|
||||||
ofdm_sync_short.cc
|
ofdm_sync_short.cc
|
||||||
ofdm_utils.cc
|
utils.cc
|
||||||
|
wave_llc_impl.cc
|
||||||
|
wave_short_message_impl.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND gr_ieee802_11_libs
|
list(APPEND gr_ieee802_11_libs
|
||||||
@@ -39,6 +126,7 @@ list(APPEND gr_ieee802_11_libs
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_library(gnuradio-ieee802_11 SHARED ${gr_ieee802_11_sources})
|
add_library(gnuradio-ieee802_11 SHARED ${gr_ieee802_11_sources})
|
||||||
|
add_dependencies(gnuradio-ieee802_11 ieee802_11_generated_includes)
|
||||||
target_link_libraries(gnuradio-ieee802_11 ${gr_ieee802_11_libs} itpp)
|
target_link_libraries(gnuradio-ieee802_11 ${gr_ieee802_11_libs} itpp)
|
||||||
set_target_properties(gnuradio-ieee802_11 PROPERTIES DEFINE_SYMBOL "gnuradio_ieee802_11_EXPORTS")
|
set_target_properties(gnuradio-ieee802_11 PROPERTIES DEFINE_SYMBOL "gnuradio_ieee802_11_EXPORTS")
|
||||||
|
|
||||||
|
|||||||
+52
-16
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "ether_encap_impl.h"
|
#include "ether_encap_impl.h"
|
||||||
#include "ofdm_parse_mac_impl.h"
|
#include "ofdm_parse_mac_impl.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
#include <gnuradio/block_detail.h>
|
#include <gnuradio/block_detail.h>
|
||||||
@@ -23,8 +24,6 @@
|
|||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
ether_encap_impl::ether_encap_impl(bool debug) :
|
ether_encap_impl::ether_encap_impl(bool debug) :
|
||||||
block("ether_encap",
|
block("ether_encap",
|
||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
@@ -32,20 +31,17 @@ ether_encap_impl::ether_encap_impl(bool debug) :
|
|||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
d_last_seq(123) {
|
d_last_seq(123) {
|
||||||
|
|
||||||
message_port_register_out(pmt::mp("out"));
|
message_port_register_out(pmt::mp("to tap"));
|
||||||
|
message_port_register_out(pmt::mp("to wifi"));
|
||||||
|
|
||||||
message_port_register_in(pmt::mp("in"));
|
message_port_register_in(pmt::mp("from tap"));
|
||||||
set_msg_handler(pmt::mp("in"), boost::bind(ðer_encap_impl::parse, this, _1));
|
set_msg_handler(pmt::mp("from tap"), boost::bind(ðer_encap_impl::from_tap, this, _1));
|
||||||
|
message_port_register_in(pmt::mp("from wifi"));
|
||||||
|
set_msg_handler(pmt::mp("from wifi"), boost::bind(ðer_encap_impl::from_wifi, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ether_encap_impl::parse(pmt::pmt_t msg) {
|
ether_encap_impl::from_wifi(pmt::pmt_t msg) {
|
||||||
|
|
||||||
if(pmt::is_eof_object(msg)) {
|
|
||||||
message_port_pub(pmt::mp("out"), pmt::PMT_EOF);
|
|
||||||
detail().get()->set_done(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = pmt::cdr(msg);
|
msg = pmt::cdr(msg);
|
||||||
|
|
||||||
@@ -59,11 +55,14 @@ ether_encap_impl::parse(pmt::pmt_t msg) {
|
|||||||
|
|
||||||
d_last_seq = mhdr->seq_control;
|
d_last_seq = mhdr->seq_control;
|
||||||
|
|
||||||
|
|
||||||
if(data_len < 33) {
|
if(data_len < 33) {
|
||||||
dout << "Ether Encap: frame too short to parse (<33)" << std::endl;
|
dout << "Ether Encap: frame too short to parse (<33)" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is more than neeed
|
||||||
|
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);
|
||||||
|
|
||||||
if(((mhdr->frame_control >> 2) & 3) != 2) {
|
if(((mhdr->frame_control >> 2) & 3) != 2) {
|
||||||
@@ -71,8 +70,8 @@ ether_encap_impl::parse(pmt::pmt_t msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ehdr->dest, mhdr->addr1, 6);
|
std::memcpy(ehdr->dest, mhdr->addr1, 6);
|
||||||
memcpy(ehdr->src, mhdr->addr2, 6);
|
std::memcpy(ehdr->src, mhdr->addr2, 6);
|
||||||
ehdr->type = 0x0008;
|
ehdr->type = 0x0008;
|
||||||
|
|
||||||
char *frame = (char*)pmt::blob_data(msg);
|
char *frame = (char*)pmt::blob_data(msg);
|
||||||
@@ -81,15 +80,52 @@ ether_encap_impl::parse(pmt::pmt_t msg) {
|
|||||||
if((((mhdr->frame_control) >> 2) & 63) == 2) {
|
if((((mhdr->frame_control) >> 2) & 63) == 2) {
|
||||||
memcpy(buf + sizeof(ethernet_header), frame + 32, data_len - 32);
|
memcpy(buf + sizeof(ethernet_header), frame + 32, data_len - 32);
|
||||||
pmt::pmt_t payload = pmt::make_blob(buf, data_len - 32 + 14);
|
pmt::pmt_t payload = pmt::make_blob(buf, data_len - 32 + 14);
|
||||||
message_port_pub(pmt::mp("out"), pmt::cons(pmt::PMT_NIL, payload));
|
message_port_pub(pmt::mp("to tap"), pmt::cons(pmt::PMT_NIL, payload));
|
||||||
|
|
||||||
// QoS Data
|
// QoS Data
|
||||||
} else if((((mhdr->frame_control) >> 2) & 63) == 34) {
|
} else if((((mhdr->frame_control) >> 2) & 63) == 34) {
|
||||||
|
|
||||||
memcpy(buf + sizeof(ethernet_header), frame + 34, data_len - 34);
|
memcpy(buf + sizeof(ethernet_header), frame + 34, data_len - 34);
|
||||||
pmt::pmt_t payload = pmt::make_blob(buf, data_len - 34 + 14);
|
pmt::pmt_t payload = pmt::make_blob(buf, data_len - 34 + 14);
|
||||||
message_port_pub(pmt::mp("out"), pmt::cons(pmt::PMT_NIL, payload));
|
message_port_pub(pmt::mp("to tap"), pmt::cons(pmt::PMT_NIL, payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ether_encap_impl::from_tap(pmt::pmt_t msg) {
|
||||||
|
size_t len = pmt::blob_length(pmt::cdr(msg));
|
||||||
|
const char* data = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
|
||||||
|
|
||||||
|
const ethernet_header *ehdr = reinterpret_cast<const ethernet_header*>(data);
|
||||||
|
|
||||||
|
switch(ehdr->type) {
|
||||||
|
case 0x0008: {
|
||||||
|
std::cout << "ether type: IP" << std::endl;
|
||||||
|
|
||||||
|
char *buf = static_cast<char*>(malloc(len + 8 - sizeof(ethernet_header)));
|
||||||
|
buf[0] = 0xaa;
|
||||||
|
buf[1] = 0xaa;
|
||||||
|
buf[2] = 0x03;
|
||||||
|
buf[3] = 0x00;
|
||||||
|
buf[4] = 0x00;
|
||||||
|
buf[5] = 0x00;
|
||||||
|
buf[6] = 0x08;
|
||||||
|
buf[7] = 0x00;
|
||||||
|
std::memcpy(buf + 8, data + sizeof(ethernet_header), len - sizeof(ethernet_header));
|
||||||
|
pmt::pmt_t blob = pmt::make_blob(buf, len + 8 - sizeof(ethernet_header));
|
||||||
|
message_port_pub(pmt::mp("to wifi"), pmt::cons(pmt::PMT_NIL, blob));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0608:
|
||||||
|
std::cout << "ether type: ARP " << std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout << "unknown ether type" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ether_encap::sptr
|
ether_encap::sptr
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ namespace ieee802_11 {
|
|||||||
ether_encap_impl(bool debug);
|
ether_encap_impl(bool debug);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parse(pmt::pmt_t msg);
|
void from_tap(pmt::pmt_t msg);
|
||||||
|
void from_wifi(pmt::pmt_t msg);
|
||||||
|
|
||||||
bool d_debug;
|
bool d_debug;
|
||||||
char buf[3000];
|
|
||||||
uint16_t d_last_seq;
|
uint16_t d_last_seq;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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 "@NAME_IMPL@.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
@NAME_IMPL@::@NAME_IMPL@(int length) :
|
||||||
|
sync_block("@NAME@",
|
||||||
|
io_signature::make(1, 1, sizeof(@I_TYPE@)),
|
||||||
|
io_signature::make(1, 1, sizeof(@O_TYPE@))),
|
||||||
|
d_length(length),
|
||||||
|
d_new_length(length),
|
||||||
|
d_updated(false) {
|
||||||
|
set_history(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@NAME_IMPL@::set_length(int length) {
|
||||||
|
d_new_length = length;
|
||||||
|
d_updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
@NAME_IMPL@::work(int noutput_items, gr_vector_const_void_star
|
||||||
|
&input_items, gr_vector_void_star &output_items) {
|
||||||
|
|
||||||
|
if(d_updated) {
|
||||||
|
d_length = d_new_length;
|
||||||
|
set_history(d_length);
|
||||||
|
d_updated = false;
|
||||||
|
return 0; // history requirements might have changed
|
||||||
|
}
|
||||||
|
|
||||||
|
const @I_TYPE@ *in = (const @I_TYPE@ *)input_items[0];
|
||||||
|
@O_TYPE@ *out = (@O_TYPE@ *)output_items[0];
|
||||||
|
|
||||||
|
@I_TYPE@ sum = 0;
|
||||||
|
for(int i = 0; i < d_length-1; i++) {
|
||||||
|
sum += in[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < noutput_items; i++) {
|
||||||
|
sum += in[i + d_length - 1];
|
||||||
|
out[i] = sum;
|
||||||
|
sum -= in[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return noutput_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NAME@::sptr
|
||||||
|
@NAME@::make(int length) {
|
||||||
|
return gnuradio::get_initial_sptr(new @NAME_IMPL@(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace blocks */
|
||||||
|
} /* namespace gr */
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef @GUARD_NAME_IMPL@
|
||||||
|
#define @GUARD_NAME_IMPL@
|
||||||
|
|
||||||
|
#include <ieee802-11/@NAME@.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class @NAME_IMPL@ : public @NAME@
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int d_length;
|
||||||
|
int d_new_length;
|
||||||
|
bool d_updated;
|
||||||
|
|
||||||
|
public:
|
||||||
|
@NAME_IMPL@(int length);
|
||||||
|
|
||||||
|
int length() const { return d_new_length; }
|
||||||
|
void set_length(int length);
|
||||||
|
|
||||||
|
int work(int noutput_items,
|
||||||
|
gr_vector_const_void_star &input_items,
|
||||||
|
gr_vector_void_star &output_items);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace blocks */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
||||||
|
#endif /* @GUARD_NAME_IMPL@ */
|
||||||
+125
-48
@@ -16,12 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
#include <ieee802-11/ofdm_decode_mac.h>
|
#include <ieee802-11/ofdm_decode_mac.h>
|
||||||
|
|
||||||
#include "ofdm_utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <boost/crc.hpp>
|
#include <boost/crc.hpp>
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
#include <itpp/itcomm.h>
|
#include <itpp/itcomm.h>
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
@@ -29,17 +28,86 @@ using namespace itpp;
|
|||||||
|
|
||||||
class ofdm_decode_mac_impl : public ofdm_decode_mac {
|
class ofdm_decode_mac_impl : public ofdm_decode_mac {
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_decode_mac_impl(bool debug) : block("ofdm_decode_mac",
|
ofdm_decode_mac_impl(bool log, bool debug) : block("ofdm_decode_mac",
|
||||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
||||||
gr::io_signature::make(0, 0, 0)),
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_log(log),
|
||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
ofdm(BPSK_1_2),
|
ofdm(BPSK_1_2),
|
||||||
tx(ofdm, 0) {
|
tx(ofdm, 0) {
|
||||||
|
|
||||||
message_port_register_out(pmt::mp("out"));
|
message_port_register_out(pmt::mp("out"));
|
||||||
|
|
||||||
|
// bpsk
|
||||||
|
std::complex<double> bpsk_syms[] = {std::complex<double>(-1, 0), std::complex<double>(1, 0)};
|
||||||
|
int bpsk_bits[] = {0, 1};
|
||||||
|
bpsk.set(cvec(bpsk_syms, 2), ivec(bpsk_bits, 2));
|
||||||
|
|
||||||
|
// qpsk
|
||||||
|
std::complex<double> qpsk_syms[] = {
|
||||||
|
std::complex<double>(-1, -1), std::complex<double>(-1, 1),
|
||||||
|
std::complex<double>( 1, -1), std::complex<double>( 1, 1)};
|
||||||
|
int qpsk_bits[] = {0, 1, 2, 3};
|
||||||
|
qpsk.set(cvec(qpsk_syms, 4), ivec(qpsk_bits, 4));
|
||||||
|
|
||||||
|
// qam16
|
||||||
|
std::complex<double> qam16_syms[] = {
|
||||||
|
std::complex<double>(-0.9487, -0.9487), std::complex<double>(-0.9487, -0.3162),
|
||||||
|
std::complex<double>(-0.9487, 0.9487), std::complex<double>(-0.9487, 0.3162),
|
||||||
|
std::complex<double>(-0.3162, -0.9487), std::complex<double>(-0.3162, -0.3162),
|
||||||
|
std::complex<double>(-0.3162, 0.9487), std::complex<double>(-0.3162, 0.3162),
|
||||||
|
std::complex<double>(0.9487, -0.9487), std::complex<double>(0.9487, -0.3162),
|
||||||
|
std::complex<double>(0.9487, 0.9487), std::complex<double>(0.9487, 0.3162),
|
||||||
|
std::complex<double>(0.3162, -0.9487), std::complex<double>(0.3162, -0.3162),
|
||||||
|
std::complex<double>(0.3162, 0.9487), std::complex<double>(0.3162, 0.3162)};
|
||||||
|
int qam16_bits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||||
|
qam16.set(cvec(qam16_syms, 16), ivec(qam16_bits, 16));
|
||||||
|
|
||||||
|
// qam64
|
||||||
|
std::complex<double> qam64_syms[] = {
|
||||||
|
std::complex<double>(-1.0801, -1.0801), std::complex<double>(-1.0801, -0.7715),
|
||||||
|
std::complex<double>(-1.0801, -0.1543), std::complex<double>(-1.0801, -0.4629),
|
||||||
|
std::complex<double>(-1.0801, 1.0801), std::complex<double>(-1.0801, 0.7715),
|
||||||
|
std::complex<double>(-1.0801, 0.1543), std::complex<double>(-1.0801, 0.4629),
|
||||||
|
std::complex<double>(-0.7715, -1.0801), std::complex<double>(-0.7715, -0.7715),
|
||||||
|
std::complex<double>(-0.7715, -0.1543), std::complex<double>(-0.7715, -0.4629),
|
||||||
|
std::complex<double>(-0.7715, 1.0801), std::complex<double>(-0.7715, 0.7715),
|
||||||
|
std::complex<double>(-0.7715, 0.1543), std::complex<double>(-0.7715, 0.4629),
|
||||||
|
std::complex<double>(-0.1543, -1.0801), std::complex<double>(-0.1543, -0.7715),
|
||||||
|
std::complex<double>(-0.1543, -0.1543), std::complex<double>(-0.1543, -0.4629),
|
||||||
|
std::complex<double>(-0.1543, 1.0801), std::complex<double>(-0.1543, 0.7715),
|
||||||
|
std::complex<double>(-0.1543, 0.1543), std::complex<double>(-0.1543, 0.4629),
|
||||||
|
std::complex<double>(-0.4629, -1.0801), std::complex<double>(-0.4629, -0.7715),
|
||||||
|
std::complex<double>(-0.4629, -0.1543), std::complex<double>(-0.4629, -0.4629),
|
||||||
|
std::complex<double>(-0.4629, 1.0801), std::complex<double>(-0.4629, 0.7715),
|
||||||
|
std::complex<double>(-0.4629, 0.1543), std::complex<double>(-0.4629, 0.4629),
|
||||||
|
std::complex<double>(1.0801, -1.0801), std::complex<double>(1.0801, -0.7715),
|
||||||
|
std::complex<double>(1.0801, -0.1543), std::complex<double>(1.0801, -0.4629),
|
||||||
|
std::complex<double>(1.0801, 1.0801), std::complex<double>(1.0801, 0.7715),
|
||||||
|
std::complex<double>(1.0801, 0.1543), std::complex<double>(1.0801, 0.4629),
|
||||||
|
std::complex<double>(0.7715, -1.0801), std::complex<double>(0.7715, -0.7715),
|
||||||
|
std::complex<double>(0.7715, -0.1543), std::complex<double>(0.7715, -0.4629),
|
||||||
|
std::complex<double>(0.7715, 1.0801), std::complex<double>(0.7715, 0.7715),
|
||||||
|
std::complex<double>(0.7715, 0.1543), std::complex<double>(0.7715, 0.4629),
|
||||||
|
std::complex<double>(0.1543, -1.0801), std::complex<double>(0.1543, -0.7715),
|
||||||
|
std::complex<double>(0.1543, -0.1543), std::complex<double>(0.1543, -0.4629),
|
||||||
|
std::complex<double>(0.1543, 1.0801), std::complex<double>(0.1543, 0.7715),
|
||||||
|
std::complex<double>(0.1543, 0.1543), std::complex<double>(0.1543, 0.4629),
|
||||||
|
std::complex<double>(0.4629, -1.0801), std::complex<double>(0.4629, -0.7715),
|
||||||
|
std::complex<double>(0.4629, -0.1543), std::complex<double>(0.4629, -0.4629),
|
||||||
|
std::complex<double>(0.4629, 1.0801), std::complex<double>(0.4629, 0.7715),
|
||||||
|
std::complex<double>(0.4629, 0.1543), std::complex<double>(0.4629, 0.4629)};
|
||||||
|
|
||||||
|
int qam64_bits[] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||||
|
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||||
|
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||||
|
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||||
|
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||||
|
60, 61, 62, 63};
|
||||||
|
qam64.set(cvec(qam64_syms, 64), ivec(qam64_bits, 64));
|
||||||
}
|
}
|
||||||
|
|
||||||
~ofdm_decode_mac_impl(){
|
~ofdm_decode_mac_impl(){
|
||||||
@@ -68,13 +136,16 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
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 = ofdm_param((Encoding)encoding);
|
||||||
tx = tx_param(ofdm, len_data);
|
tx = tx_param(ofdm, len_data);
|
||||||
|
|
||||||
if(tx.n_sym > 100) {
|
|
||||||
tx.n_sym = 100;
|
|
||||||
}
|
|
||||||
copied = 0;
|
copied = 0;
|
||||||
|
|
||||||
|
// this frame is garbage
|
||||||
|
if(tx.n_sym > 100) {
|
||||||
|
// FIXME: make this nicer, this way garbage frames are skipped
|
||||||
|
copied = tx.n_sym + 1;
|
||||||
|
}
|
||||||
dout << "Decode MAC: frame start -- len " << len_data
|
dout << "Decode MAC: frame start -- len " << len_data
|
||||||
<< " symbols " << tx.n_sym << " encoding "
|
<< " symbols " << tx.n_sym << " encoding "
|
||||||
<< encoding << std::endl;
|
<< encoding << std::endl;
|
||||||
@@ -102,9 +173,6 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void decode() {
|
void decode() {
|
||||||
if(ofdm.encoding > 3) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
demodulate();
|
demodulate();
|
||||||
deinterleave();
|
deinterleave();
|
||||||
decode_conv();
|
decode_conv();
|
||||||
@@ -119,6 +187,9 @@ void decode() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||||
|
% ofdm.encoding % tx.psdu_size % 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, tx.psdu_size - 4);
|
||||||
pmt::pmt_t enc = pmt::from_uint64(ofdm.encoding);
|
pmt::pmt_t enc = pmt::from_uint64(ofdm.encoding);
|
||||||
@@ -128,36 +199,38 @@ void decode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void demodulate() {
|
void demodulate() {
|
||||||
gr_complex s;
|
|
||||||
for(int i = 0; i < tx.n_sym; i++) {
|
cvec symbols;
|
||||||
for(int n = 0; n < 48; n++) {
|
symbols.set_length(tx.n_sym * 48);
|
||||||
|
for(int i = 0; i < tx.n_sym * 48; i++) {
|
||||||
|
symbols[i] = std::complex<double>(sym[i]);
|
||||||
|
}
|
||||||
|
|
||||||
switch(ofdm.encoding) {
|
switch(ofdm.encoding) {
|
||||||
case 0: // BPSK
|
case BPSK_1_2:
|
||||||
case 1:
|
case BPSK_3_4:
|
||||||
bits[i * 48 + n] = -real(sym[i * 48 + n]);
|
|
||||||
|
bits = to_vec(bpsk.demodulate_bits(symbols));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // QPSK
|
case QPSK_1_2:
|
||||||
case 3:
|
case QPSK_3_4:
|
||||||
s = sym[i * 48 + n];
|
|
||||||
bits[(i * 48 + n) * 2] = -real(s);
|
|
||||||
bits[(i * 48 + n) * 2 + 1] = -imag(s);
|
|
||||||
|
|
||||||
|
bits = to_vec(qpsk.demodulate_bits(symbols));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case QAM16_1_2:
|
||||||
case 5:
|
case QAM16_3_4:
|
||||||
case 6:
|
bits = to_vec(qam16.demodulate_bits(symbols));
|
||||||
case 7:
|
break;
|
||||||
|
case QAM64_2_3:
|
||||||
|
case QAM64_3_4:
|
||||||
default:
|
bits = to_vec(qam64.demodulate_bits(symbols));
|
||||||
assert(false);
|
break;
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I hate the guy who wrote itpp
|
||||||
|
bits = bits * (-2) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinterleave() {
|
void deinterleave() {
|
||||||
@@ -191,21 +264,20 @@ void decode_conv() {
|
|||||||
|
|
||||||
bmat puncture_matrix;
|
bmat puncture_matrix;
|
||||||
switch(ofdm.encoding) {
|
switch(ofdm.encoding) {
|
||||||
case 0:
|
case BPSK_1_2:
|
||||||
case 2:
|
case QPSK_1_2:
|
||||||
|
case QAM16_1_2:
|
||||||
puncture_matrix = "1 1; 1 1";
|
puncture_matrix = "1 1; 1 1";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case BPSK_3_4:
|
||||||
case 3:
|
case QPSK_3_4:
|
||||||
|
case QAM16_3_4:
|
||||||
|
case QAM64_3_4:
|
||||||
puncture_matrix = "1 1 0; 1 0 1;";
|
puncture_matrix = "1 1 0; 1 0 1;";
|
||||||
break;
|
break;
|
||||||
case 4:
|
case QAM64_2_3:
|
||||||
case 5:
|
puncture_matrix = "1 1 1 1 1 1; 1 0 1 0 1 0;";
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
code.set_puncture_matrix(puncture_matrix);
|
code.set_puncture_matrix(puncture_matrix);
|
||||||
code.set_truncation_length(30);
|
code.set_truncation_length(30);
|
||||||
@@ -221,7 +293,6 @@ void decode_conv() {
|
|||||||
|
|
||||||
//dout << "length decoded " << decoded_bits.size() << std::endl;
|
//dout << "length decoded " << decoded_bits.size() << std::endl;
|
||||||
//std::cout << decoded_bits << std::endl;
|
//std::cout << decoded_bits << std::endl;
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void descramble () {
|
void descramble () {
|
||||||
@@ -276,21 +347,27 @@ void print_output() {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
gr_complex sym[1000 * 48 * 100];
|
gr_complex sym[1000 * 48 * 100];
|
||||||
double bits[1000 * 48];
|
vec bits;
|
||||||
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_debug;
|
||||||
|
bool d_log;
|
||||||
tx_param tx;
|
tx_param tx;
|
||||||
ofdm_param ofdm;
|
ofdm_param ofdm;
|
||||||
int copied;
|
int copied;
|
||||||
static int scrambler_init[128];
|
static int scrambler_init[128];
|
||||||
|
|
||||||
|
Modulator<std::complex<double> > bpsk;
|
||||||
|
Modulator<std::complex<double> > qpsk;
|
||||||
|
Modulator<std::complex<double> > qam16;
|
||||||
|
Modulator<std::complex<double> > qam64;
|
||||||
};
|
};
|
||||||
|
|
||||||
ofdm_decode_mac::sptr
|
ofdm_decode_mac::sptr
|
||||||
ofdm_decode_mac::make(bool debug) {
|
ofdm_decode_mac::make(bool log, bool debug) {
|
||||||
return gnuradio::get_initial_sptr(new ofdm_decode_mac_impl(debug));
|
return gnuradio::get_initial_sptr(new ofdm_decode_mac_impl(log, debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ofdm_decode_mac_impl::scrambler_init[128] = {
|
int ofdm_decode_mac_impl::scrambler_init[128] = {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
#include <ieee802-11/ofdm_decode_signal.h>
|
#include <ieee802-11/ofdm_decode_signal.h>
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <itpp/itcomm.h>
|
#include <itpp/itcomm.h>
|
||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
@@ -26,12 +26,11 @@ using namespace itpp;
|
|||||||
|
|
||||||
class ofdm_decode_signal_impl : public ofdm_decode_signal {
|
class ofdm_decode_signal_impl : public ofdm_decode_signal {
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_decode_signal_impl(bool debug) : block("ofdm_decode_signal",
|
ofdm_decode_signal_impl(bool log, bool debug) : block("ofdm_decode_signal",
|
||||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
||||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
||||||
|
d_log(log),
|
||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
d_copy_symbols(0) {
|
d_copy_symbols(0) {
|
||||||
|
|
||||||
@@ -195,6 +194,9 @@ bool print_signal() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||||
|
% d_encoding % d_len % d_copy_symbols);
|
||||||
|
|
||||||
dout << "d_copy_symbols: " << d_copy_symbols << std::endl;
|
dout << "d_copy_symbols: " << d_copy_symbols << std::endl;
|
||||||
dout << "length: " << d_len << std::endl;
|
dout << "length: " << d_len << std::endl;
|
||||||
return true;
|
return true;
|
||||||
@@ -203,6 +205,7 @@ bool print_signal() {
|
|||||||
private:
|
private:
|
||||||
int d_len;
|
int d_len;
|
||||||
int d_encoding;
|
int d_encoding;
|
||||||
|
bool d_log;
|
||||||
bool d_debug;
|
bool d_debug;
|
||||||
double bits[48];
|
double bits[48];
|
||||||
int d_copy_symbols;
|
int d_copy_symbols;
|
||||||
@@ -211,8 +214,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
ofdm_decode_signal::sptr
|
ofdm_decode_signal::sptr
|
||||||
ofdm_decode_signal::make(bool debug) {
|
ofdm_decode_signal::make(bool log, bool debug) {
|
||||||
return gnuradio::get_initial_sptr(new ofdm_decode_signal_impl(debug));
|
return gnuradio::get_initial_sptr(new ofdm_decode_signal_impl(log, debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ofdm_decode_signal_impl::inter[48]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47};
|
int ofdm_decode_signal_impl::inter[48]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47};
|
||||||
|
|||||||
@@ -15,17 +15,15 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <ieee802-11/ofdm_equalize_symbols.h>
|
#include <ieee802-11/ofdm_equalize_symbols.h>
|
||||||
#include <gnuradio/io_signature.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include "utils.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
|
||||||
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
|
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_equalize_symbols_impl(bool debug) : block("ofdm_equalize_symbols",
|
ofdm_equalize_symbols_impl(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)),
|
||||||
@@ -65,6 +63,10 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
gr_complex p = POLARITY[index];
|
gr_complex p = POLARITY[index];
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
|
// FIXME: think about this... average over amplitude or power
|
||||||
|
double avg_mag = (abs(in[11]) + abs(in[25]) + abs(in[39]) + abs(in[53])) / 4;
|
||||||
|
|
||||||
|
|
||||||
double p1 = arg( p * in[11]);
|
double p1 = arg( p * in[11]);
|
||||||
double p2 = arg( p * in[25] * conj(p * in[11])) + p1;
|
double p2 = arg( p * in[25] * conj(p * in[11])) + p1;
|
||||||
double p3 = arg( p * in[39] * conj(p * in[25])) + p2;
|
double p3 = arg( p * in[39] * conj(p * in[25])) + p2;
|
||||||
@@ -83,7 +85,8 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
if( (n == 11) || (n == 25) || (n == 32) || (n == 39) || (n == 53) || (n < 6) || ( n > 58)) {
|
if( (n == 11) || (n == 25) || (n == 32) || (n == 39) || (n == 53) || (n < 6) || ( n > 58)) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
out[o] = in[n] * exp(gr_complex(0, -n * beta - alpha));
|
// 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++;
|
o++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
|
||||||
+171
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* 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_mac.h>
|
||||||
|
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <gnuradio/block_detail.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
|
#include <boost/crc.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
class ofdm_mac_impl : public ofdm_mac {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ofdm_mac_impl() :
|
||||||
|
block("ofdm_mac",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_seq_nr(0) {
|
||||||
|
|
||||||
|
message_port_register_out(pmt::mp("phy out"));
|
||||||
|
message_port_register_out(pmt::mp("app out"));
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("app in"));
|
||||||
|
set_msg_handler(pmt::mp("app in"), boost::bind(&ofdm_mac_impl::app_in, this, _1));
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("phy in"));
|
||||||
|
set_msg_handler(pmt::mp("phy in"), boost::bind(&ofdm_mac_impl::phy_in, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void phy_in (pmt::pmt_t msg) {
|
||||||
|
message_port_pub(pmt::mp("app out"), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_in (pmt::pmt_t msg) {
|
||||||
|
|
||||||
|
size_t msg_len;
|
||||||
|
const char *msdu;
|
||||||
|
|
||||||
|
if(pmt::is_eof_object(msg)) {
|
||||||
|
message_port_pub(pmt::mp("phy out"), pmt::PMT_EOF);
|
||||||
|
detail().get()->set_done(true);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if(pmt::is_symbol(msg)) {
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
str = pmt::symbol_to_string(msg);
|
||||||
|
msg_len = str.length();
|
||||||
|
msdu = str.data();
|
||||||
|
|
||||||
|
} else if(pmt::is_pair(msg)) {
|
||||||
|
|
||||||
|
msg_len = pmt::blob_length(pmt::cdr(msg));
|
||||||
|
msdu = reinterpret_cast<const char *>(pmt::blob_data(pmt::cdr(msg)));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw std::invalid_argument("OFDM MAC expects PDUs or strings");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make MAC frame
|
||||||
|
int psdu_length;
|
||||||
|
char *psdu;
|
||||||
|
generate_mac_data_frame(msdu, msg_len, &psdu, &psdu_length);
|
||||||
|
|
||||||
|
// dict
|
||||||
|
pmt::pmt_t dict = pmt::make_dict();
|
||||||
|
dict = pmt::dict_add(dict, pmt::mp("crc_included"), pmt::PMT_T);
|
||||||
|
|
||||||
|
// blob
|
||||||
|
pmt::pmt_t mac = pmt::make_blob(psdu, psdu_length);
|
||||||
|
|
||||||
|
// pdu
|
||||||
|
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) {
|
||||||
|
|
||||||
|
//mac frame
|
||||||
|
MAC_DATAFRAME_HEADER header;
|
||||||
|
//frame check sequence
|
||||||
|
unsigned int fcs;
|
||||||
|
|
||||||
|
// TODO: change this back to 0x08
|
||||||
|
header.frame_control[0] = 0x08;//0x20; //00000100 00100000 indicate DATA frame (LOL, not), to_ds, from_ds, more frag, retry
|
||||||
|
header.frame_control[1] = 0x00;//0x40; //all other flags, unutilized //00000010 01000000
|
||||||
|
|
||||||
|
header.duration[0] = 0x00; //TODO: set accordingly to payload
|
||||||
|
header.duration[1] = 0x2e; //0x74; //2e = 00101110 -> 01110100 -> 74
|
||||||
|
|
||||||
|
header.address1[0] = 0x30;
|
||||||
|
header.address1[1] = 0x14;
|
||||||
|
header.address1[2] = 0x4a;
|
||||||
|
header.address1[3] = 0xe6;
|
||||||
|
header.address1[4] = 0x46;
|
||||||
|
header.address1[5] = 0xe4;
|
||||||
|
|
||||||
|
header.address2[0] = 0x12;
|
||||||
|
header.address2[1] = 0x34;
|
||||||
|
header.address2[2] = 0x56;
|
||||||
|
header.address2[3] = 0x78;
|
||||||
|
header.address2[4] = 0x90;
|
||||||
|
header.address2[5] = 0xab;
|
||||||
|
|
||||||
|
header.address3[0] = 0x42;
|
||||||
|
header.address3[1] = 0x42;
|
||||||
|
header.address3[2] = 0x42;
|
||||||
|
header.address3[3] = 0x42;
|
||||||
|
header.address3[4] = 0x42;
|
||||||
|
header.address3[5] = 0x42;
|
||||||
|
|
||||||
|
header.sequence = 0;
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
if(d_seq_nr & (1 << i)) {
|
||||||
|
header.sequence |= (1 << (i + 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header.sequence = htole16(header.sequence);
|
||||||
|
d_seq_nr++;
|
||||||
|
|
||||||
|
//header size is 24, plus 4 for FCS means 28 bytes
|
||||||
|
*psdu_size = 28 + msdu_size;
|
||||||
|
*psdu = (char *) calloc(*psdu_size, sizeof(char));
|
||||||
|
|
||||||
|
//copy mac header into psdu
|
||||||
|
std::memcpy(*psdu, &header, 24);
|
||||||
|
//copy msdu into psdu
|
||||||
|
memcpy(*psdu + 24, msdu, msdu_size);
|
||||||
|
//compute and store fcs
|
||||||
|
boost::crc_32_type result;
|
||||||
|
result.process_bytes(*psdu, msdu_size + 24);
|
||||||
|
fcs = result.checksum();
|
||||||
|
memcpy(*psdu + msdu_size + 24, &fcs, sizeof(unsigned int));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16_t d_seq_nr;
|
||||||
|
char d_mac1[6];
|
||||||
|
char d_mac2[6];
|
||||||
|
char d_mac3[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
ofdm_mac::sptr
|
||||||
|
ofdm_mac::make() {
|
||||||
|
return gnuradio::get_initial_sptr(new ofdm_mac_impl());
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
/*
|
||||||
|
* 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_mapper.h>
|
||||||
|
#include "utils.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
|
||||||
|
class ofdm_mapper_impl : public ofdm_mapper {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static const int DATA_CARRIERS = 48;
|
||||||
|
|
||||||
|
ofdm_mapper_impl(Encoding e, bool debug) :
|
||||||
|
block ("ofdm_mapper",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(1, 1, DATA_CARRIERS * sizeof(gr_complex))),
|
||||||
|
d_symbols_offset(0),
|
||||||
|
d_symbols(NULL),
|
||||||
|
d_debug(debug),
|
||||||
|
d_ofdm(e) {
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("in"));
|
||||||
|
set_encoding(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ofdm_mapper_impl() {
|
||||||
|
free(d_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_message(const char *msg, size_t len) {
|
||||||
|
|
||||||
|
dout << std::hex << "OFDM MAPPER input symbols" << std::endl
|
||||||
|
<< "===========================" << std::endl;
|
||||||
|
|
||||||
|
for(int i = 0; i < len; i++) {
|
||||||
|
dout << std::hex << (int)msg[i] << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
dout << std::dec << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_to_symbols(const char *bits, size_t len) {
|
||||||
|
|
||||||
|
dout << "OFDM MAPPER complex symbols" << std::endl
|
||||||
|
<< "===========================" << std::endl;
|
||||||
|
|
||||||
|
for(int i = 0; i < len; i++) {
|
||||||
|
|
||||||
|
// the signal field is bpsk encoded
|
||||||
|
d_symbols[i] = (i < 48) ? bpsk_mapping[bits[i]] : mapping[bits[i]];
|
||||||
|
dout << d_symbols[i] << " ";
|
||||||
|
}
|
||||||
|
dout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int general_work(int noutput, gr_vector_int& ninput_items,
|
||||||
|
gr_vector_const_void_star& input_items,
|
||||||
|
gr_vector_void_star& output_items ) {
|
||||||
|
|
||||||
|
gr_complex *out = (gr_complex*)output_items[0];
|
||||||
|
dout << "OFDM MAPPER called offset: " << d_symbols_offset <<
|
||||||
|
" length: " << d_symbols_len << std::endl;
|
||||||
|
|
||||||
|
while(!d_symbols_offset) {
|
||||||
|
pmt::pmt_t msg(delete_head_blocking(pmt::intern("in")));
|
||||||
|
|
||||||
|
if(pmt::is_eof_object(msg)) {
|
||||||
|
dout << "MAPPER: exiting" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pmt::is_pair(msg)) {
|
||||||
|
dout << "OFDM MAPPER: received new message" << std::endl;
|
||||||
|
gr::thread::scoped_lock lock(d_mutex);
|
||||||
|
|
||||||
|
int psdu_length = pmt::blob_length(pmt::cdr(msg));
|
||||||
|
const char *psdu = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
|
||||||
|
|
||||||
|
|
||||||
|
// ############ INSERT MAC STUFF
|
||||||
|
tx_param tx(d_ofdm, psdu_length);
|
||||||
|
//tx.print_out();
|
||||||
|
//ofdm.print_out();
|
||||||
|
|
||||||
|
//alloc memory for modulation steps
|
||||||
|
char *data_bits = (char*)calloc(tx.n_data, sizeof(char));
|
||||||
|
char *scrambled_data = (char*)calloc(tx.n_data, sizeof(char));
|
||||||
|
char *encoded_data = (char*)calloc(tx.n_data * 2, sizeof(char));
|
||||||
|
char *punctured_data = (char*)calloc(tx.n_encoded_bits, sizeof(char));
|
||||||
|
char *interleaved_data = (char*)calloc(tx.n_encoded_bits, sizeof(char));
|
||||||
|
char *symbols = (char*)calloc((tx.n_encoded_bits / d_ofdm.n_bpsc) + 48, sizeof(char));
|
||||||
|
|
||||||
|
//generate the OFDM data field, adding service field and pad bits
|
||||||
|
generate_bits(psdu, data_bits, tx);
|
||||||
|
//print_hex_array(data_bits, tx.n_data);
|
||||||
|
|
||||||
|
// first step, scrambling
|
||||||
|
scramble(data_bits, scrambled_data, tx, 23);
|
||||||
|
//print_hex_array(scrambled_data, tx.n_data);
|
||||||
|
// reset tail bits
|
||||||
|
reset_tail_bits(scrambled_data, tx);
|
||||||
|
//print_hex_array(scrambled_data, tx.n_data);
|
||||||
|
// encoding
|
||||||
|
convolutional_encoding(scrambled_data, encoded_data, tx);
|
||||||
|
//print_hex_array(encoded_data, tx.n_data * 2);
|
||||||
|
// puncturing
|
||||||
|
puncturing(encoded_data, punctured_data, tx, d_ofdm);
|
||||||
|
//std::cout << "punctured" << std::endl;
|
||||||
|
// interleaving
|
||||||
|
interleave(punctured_data, interleaved_data, tx, d_ofdm);
|
||||||
|
//std::cout << "interleaved" << std::endl;
|
||||||
|
|
||||||
|
split_symbols(interleaved_data, symbols + 48, tx, d_ofdm);
|
||||||
|
//std::cout << "split" << std::endl;
|
||||||
|
generate_signal_field(symbols, tx, d_ofdm);
|
||||||
|
//std::cout << "signal" << std::endl;
|
||||||
|
|
||||||
|
d_symbols_len = (tx.n_sym + 1) * 48;
|
||||||
|
assert(d_symbols_len % 48 == 0);
|
||||||
|
|
||||||
|
|
||||||
|
// ############ INSERT MAC STUFF
|
||||||
|
|
||||||
|
d_symbols = static_cast<gr_complex*>(std::malloc(d_symbols_len * sizeof(gr_complex)));
|
||||||
|
|
||||||
|
|
||||||
|
print_message(static_cast<const char*>(symbols), d_symbols_len);
|
||||||
|
map_to_symbols(static_cast<const char*>(symbols), d_symbols_len);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// add tag to indicate start of odfm frame
|
||||||
|
const pmt::pmt_t key = pmt::string_to_symbol("ofdm_start");
|
||||||
|
const pmt::pmt_t value = pmt::from_uint64((d_symbols_len / DATA_CARRIERS));
|
||||||
|
const pmt::pmt_t srcid = pmt::string_to_symbol(this->name());
|
||||||
|
add_item_tag(0, this->nitems_written(0), key, value, srcid);
|
||||||
|
|
||||||
|
|
||||||
|
free(data_bits);
|
||||||
|
free(scrambled_data);
|
||||||
|
free(encoded_data);
|
||||||
|
free(punctured_data);
|
||||||
|
free(interleaved_data);
|
||||||
|
free(symbols);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while(i < noutput) {
|
||||||
|
|
||||||
|
memcpy(out, d_symbols + d_symbols_offset, DATA_CARRIERS * sizeof(gr_complex));
|
||||||
|
|
||||||
|
i++;
|
||||||
|
d_symbols_offset += DATA_CARRIERS;
|
||||||
|
out += DATA_CARRIERS;
|
||||||
|
|
||||||
|
if(d_symbols_offset == d_symbols_len) {
|
||||||
|
d_symbols_offset = 0;
|
||||||
|
free(d_symbols);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dout << "OFDM MAPPER: output size: " << noutput <<
|
||||||
|
" produced items: " << i << std::endl;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_encoding(Encoding encoding) {
|
||||||
|
|
||||||
|
std::cout << "OFDM MAPPER: encoding: " << encoding << std::endl;
|
||||||
|
gr::thread::scoped_lock lock(d_mutex);
|
||||||
|
|
||||||
|
d_ofdm = ofdm_param(encoding);
|
||||||
|
|
||||||
|
switch (encoding) {
|
||||||
|
case BPSK_1_2:
|
||||||
|
case BPSK_3_4:
|
||||||
|
mapping = bpsk_mapping;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QPSK_1_2:
|
||||||
|
case QPSK_3_4:
|
||||||
|
mapping = qpsk_mapping;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM16_1_2:
|
||||||
|
case QAM16_3_4:
|
||||||
|
mapping = qam16_mapping;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM64_2_3:
|
||||||
|
case QAM64_3_4:
|
||||||
|
mapping = qam64_mapping;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("wrong encoding");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool d_debug;
|
||||||
|
gr_complex* d_symbols;
|
||||||
|
int d_symbols_offset;
|
||||||
|
int d_symbols_len;
|
||||||
|
ofdm_param d_ofdm;
|
||||||
|
gr::thread::mutex d_mutex;
|
||||||
|
|
||||||
|
const gr_complex *mapping;
|
||||||
|
static const gr_complex bpsk_mapping[2];
|
||||||
|
static const gr_complex qpsk_mapping[4];
|
||||||
|
static const gr_complex qam16_mapping[16];
|
||||||
|
static const gr_complex qam64_mapping[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
// constellations for different modulations (normalized to avg power 1)
|
||||||
|
const gr_complex ofdm_mapper_impl::bpsk_mapping[2] = {
|
||||||
|
gr_complex(-1.0, 0.0), gr_complex(1.0, 0.0)};
|
||||||
|
const gr_complex ofdm_mapper_impl::qpsk_mapping[4] = {
|
||||||
|
gr_complex(-0.7071, -0.7071), gr_complex(-0.7071, 0.7071),
|
||||||
|
gr_complex(+0.7071, -0.7071), gr_complex(+0.7071, 0.7071)};
|
||||||
|
const gr_complex ofdm_mapper_impl::qam16_mapping[16] = {
|
||||||
|
gr_complex(-0.9487, -0.9487), gr_complex(-0.9487, -0.3162),
|
||||||
|
gr_complex(-0.9487, 0.9487), gr_complex(-0.9487, 0.3162),
|
||||||
|
gr_complex(-0.3162, -0.9487), gr_complex(-0.3162, -0.3162),
|
||||||
|
gr_complex(-0.3162, 0.9487), gr_complex(-0.3162, 0.3162),
|
||||||
|
gr_complex(0.9487, -0.9487), gr_complex(0.9487, -0.3162),
|
||||||
|
gr_complex(0.9487, 0.9487), gr_complex(0.9487, 0.3162),
|
||||||
|
gr_complex(0.3162, -0.9487), gr_complex(0.3162, -0.3162),
|
||||||
|
gr_complex(0.3162, 0.9487), gr_complex(0.3162, 0.3162)};
|
||||||
|
const gr_complex ofdm_mapper_impl::qam64_mapping[64] = {
|
||||||
|
gr_complex(-1.0801, -1.0801), gr_complex(-1.0801, -0.7715),
|
||||||
|
gr_complex(-1.0801, -0.1543), gr_complex(-1.0801, -0.4629),
|
||||||
|
gr_complex(-1.0801, 1.0801), gr_complex(-1.0801, 0.7715),
|
||||||
|
gr_complex(-1.0801, 0.1543), gr_complex(-1.0801, 0.4629),
|
||||||
|
gr_complex(-0.7715, -1.0801), gr_complex(-0.7715, -0.7715),
|
||||||
|
gr_complex(-0.7715, -0.1543), gr_complex(-0.7715, -0.4629),
|
||||||
|
gr_complex(-0.7715, 1.0801), gr_complex(-0.7715, 0.7715),
|
||||||
|
gr_complex(-0.7715, 0.1543), gr_complex(-0.7715, 0.4629),
|
||||||
|
gr_complex(-0.1543, -1.0801), gr_complex(-0.1543, -0.7715),
|
||||||
|
gr_complex(-0.1543, -0.1543), gr_complex(-0.1543, -0.4629),
|
||||||
|
gr_complex(-0.1543, 1.0801), gr_complex(-0.1543, 0.7715),
|
||||||
|
gr_complex(-0.1543, 0.1543), gr_complex(-0.1543, 0.4629),
|
||||||
|
gr_complex(-0.4629, -1.0801), gr_complex(-0.4629, -0.7715),
|
||||||
|
gr_complex(-0.4629, -0.1543), gr_complex(-0.4629, -0.4629),
|
||||||
|
gr_complex(-0.4629, 1.0801), gr_complex(-0.4629, 0.7715),
|
||||||
|
gr_complex(-0.4629, 0.1543), gr_complex(-0.4629, 0.4629),
|
||||||
|
gr_complex(1.0801, -1.0801), gr_complex(1.0801, -0.7715),
|
||||||
|
gr_complex(1.0801, -0.1543), gr_complex(1.0801, -0.4629),
|
||||||
|
gr_complex(1.0801, 1.0801), gr_complex(1.0801, 0.7715),
|
||||||
|
gr_complex(1.0801, 0.1543), gr_complex(1.0801, 0.4629),
|
||||||
|
gr_complex(0.7715, -1.0801), gr_complex(0.7715, -0.7715),
|
||||||
|
gr_complex(0.7715, -0.1543), gr_complex(0.7715, -0.4629),
|
||||||
|
gr_complex(0.7715, 1.0801), gr_complex(0.7715, 0.7715),
|
||||||
|
gr_complex(0.7715, 0.1543), gr_complex(0.7715, 0.4629),
|
||||||
|
gr_complex(0.1543, -1.0801), gr_complex(0.1543, -0.7715),
|
||||||
|
gr_complex(0.1543, -0.1543), gr_complex(0.1543, -0.4629),
|
||||||
|
gr_complex(0.1543, 1.0801), gr_complex(0.1543, 0.7715),
|
||||||
|
gr_complex(0.1543, 0.1543), gr_complex(0.1543, 0.4629),
|
||||||
|
gr_complex(0.4629, -1.0801), gr_complex(0.4629, -0.7715),
|
||||||
|
gr_complex(0.4629, -0.1543), gr_complex(0.4629, -0.4629),
|
||||||
|
gr_complex(0.4629, 1.0801), gr_complex(0.4629, 0.7715),
|
||||||
|
gr_complex(0.4629, 0.1543), gr_complex(0.4629, 0.4629)};
|
||||||
|
|
||||||
|
|
||||||
|
ofdm_mapper::sptr
|
||||||
|
ofdm_mapper::make(Encoding mcs, bool debug) {
|
||||||
|
return gnuradio::get_initial_sptr(new ofdm_mapper_impl(mcs, debug));
|
||||||
|
}
|
||||||
+10
-15
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <ieee802-11/ofdm_parse_mac.h>
|
#include <ieee802-11/ofdm_parse_mac.h>
|
||||||
#include "ofdm_parse_mac_impl.h"
|
#include "ofdm_parse_mac_impl.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
#include <gnuradio/block_detail.h>
|
#include <gnuradio/block_detail.h>
|
||||||
@@ -25,18 +26,15 @@ using namespace gr::ieee802_11;
|
|||||||
|
|
||||||
class ofdm_parse_mac_impl : public ofdm_parse_mac {
|
class ofdm_parse_mac_impl : public ofdm_parse_mac {
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ofdm_parse_mac_impl(bool debug) :
|
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_debug(debug) {
|
d_debug(debug) {
|
||||||
|
|
||||||
message_port_register_out(pmt::mp("out"));
|
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
@@ -48,9 +46,10 @@ ofdm_parse_mac_impl(bool debug) :
|
|||||||
void parse(pmt::pmt_t msg) {
|
void parse(pmt::pmt_t msg) {
|
||||||
|
|
||||||
if(pmt::is_eof_object(msg)) {
|
if(pmt::is_eof_object(msg)) {
|
||||||
message_port_pub(pmt::mp("out"), pmt::PMT_EOF);
|
|
||||||
detail().get()->set_done(true);
|
detail().get()->set_done(true);
|
||||||
return;
|
return;
|
||||||
|
} else if(pmt::is_symbol(msg)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = pmt::cdr(msg);
|
msg = pmt::cdr(msg);
|
||||||
@@ -58,6 +57,8 @@ void parse(pmt::pmt_t msg) {
|
|||||||
int data_len = pmt::blob_length(msg);
|
int data_len = pmt::blob_length(msg);
|
||||||
mac_header *h = (mac_header*)pmt::blob_data(msg);
|
mac_header *h = (mac_header*)pmt::blob_data(msg);
|
||||||
|
|
||||||
|
mylog(boost::format("length: %1%") % data_len );
|
||||||
|
|
||||||
dout << std::endl << "new mac frame (length " << data_len << ")" << std::endl;
|
dout << std::endl << "new mac frame (length " << data_len << ")" << std::endl;
|
||||||
dout << "=========================================" << std::endl;
|
dout << "=========================================" << std::endl;
|
||||||
if(data_len < 20) {
|
if(data_len < 20) {
|
||||||
@@ -68,7 +69,6 @@ void parse(pmt::pmt_t msg) {
|
|||||||
dout << "duration: " << HEX(h->duration >> 8) << " " << HEX(h->duration & 0xff) << std::endl;
|
dout << "duration: " << HEX(h->duration >> 8) << " " << HEX(h->duration & 0xff) << std::endl;
|
||||||
dout << "frame control: " << HEX(h->frame_control >> 8) << " " << HEX(h->frame_control & 0xff);
|
dout << "frame control: " << HEX(h->frame_control >> 8) << " " << HEX(h->frame_control & 0xff);
|
||||||
|
|
||||||
|
|
||||||
switch((h->frame_control >> 2) & 3) {
|
switch((h->frame_control >> 2) & 3) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
@@ -99,15 +99,9 @@ void parse(pmt::pmt_t msg) {
|
|||||||
// DATA
|
// DATA
|
||||||
if((((h->frame_control) >> 2) & 63) == 2) {
|
if((((h->frame_control) >> 2) & 63) == 2) {
|
||||||
print_ascii(frame + 24, data_len - 24);
|
print_ascii(frame + 24, data_len - 24);
|
||||||
pmt::pmt_t payload = pmt::make_blob(frame + 24, data_len - 24);
|
|
||||||
|
|
||||||
message_port_pub(pmt::mp("out"), pmt::cons(pmt::PMT_NIL, payload));
|
|
||||||
// QoS Data
|
// QoS Data
|
||||||
} else if((((h->frame_control) >> 2) & 63) == 34) {
|
} else if((((h->frame_control) >> 2) & 63) == 34) {
|
||||||
print_ascii(frame + 26, data_len - 26);
|
print_ascii(frame + 26, data_len - 26);
|
||||||
pmt::pmt_t payload = pmt::make_blob(frame + 26, data_len - 26);
|
|
||||||
|
|
||||||
message_port_pub(pmt::mp("out"), pmt::cons(pmt::PMT_NIL, payload));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,13 +340,14 @@ void print_ascii(char* buf, int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool d_log;
|
||||||
bool d_debug;
|
bool d_debug;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ofdm_parse_mac::sptr
|
ofdm_parse_mac::sptr
|
||||||
ofdm_parse_mac::make(bool debug) {
|
ofdm_parse_mac::make(bool log, bool debug) {
|
||||||
return gnuradio::get_initial_sptr(new ofdm_parse_mac_impl(debug));
|
return gnuradio::get_initial_sptr(new ofdm_parse_mac_impl(log, debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* 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_pilot.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
|
||||||
|
class ofdm_pilot_impl : public ofdm_pilot {
|
||||||
|
|
||||||
|
static const int TONES = 48;
|
||||||
|
static const int FFT_SIZE = 64;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ofdm_pilot_impl(bool debug) :
|
||||||
|
sync_block ("ofdm_pilot",
|
||||||
|
gr::io_signature::make(1, 1, TONES * sizeof(gr_complex)),
|
||||||
|
gr::io_signature::make(1, 1, FFT_SIZE * sizeof(gr_complex))),
|
||||||
|
d_offset(0),
|
||||||
|
d_debug(debug) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~ofdm_pilot_impl() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int work (int noutput_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];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int count = 0;
|
||||||
|
const uint64_t nread = nitems_read(0);
|
||||||
|
std::vector<gr::tag_t> tags;
|
||||||
|
|
||||||
|
while (count < noutput_items) {
|
||||||
|
|
||||||
|
get_tags_in_range(tags, 0, nread + count, nread + count + 1, pmt::string_to_symbol("ofdm_start"));
|
||||||
|
|
||||||
|
if(tags.size()) {
|
||||||
|
d_offset = 0;
|
||||||
|
dout << "OFDM PILOT: start of OFDM frame" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// guard band
|
||||||
|
memset(out, 0, 6 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// subcarriers -26 to -22
|
||||||
|
memcpy(out + 6, in, 5 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// pilot 1
|
||||||
|
out[11] = POLARITY[d_offset];
|
||||||
|
|
||||||
|
// subcarriers -20 to -8
|
||||||
|
memcpy(out + 12, in + 5, 13 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// pilot 2
|
||||||
|
out[25] = POLARITY[d_offset];
|
||||||
|
|
||||||
|
// subcarriers -6 to -1
|
||||||
|
memcpy(out + 26, in + 18, 6 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// DC
|
||||||
|
out[32] = 0;
|
||||||
|
|
||||||
|
// subcarriers 1 to 6
|
||||||
|
memcpy(out + 33, in + 24, 6 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// pilot 3
|
||||||
|
out[39] = POLARITY[d_offset];
|
||||||
|
|
||||||
|
// pubcarriers 8 to 20
|
||||||
|
memcpy(out + 40, in + 30, 13 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// pilot 4
|
||||||
|
out[53] = -POLARITY[d_offset];
|
||||||
|
|
||||||
|
// subcarriers 22 to 26
|
||||||
|
memcpy(out + 54, in + 43, 5 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
// guard band
|
||||||
|
memset(out + 59, 0, 5 * sizeof(gr_complex));
|
||||||
|
|
||||||
|
|
||||||
|
count++;
|
||||||
|
out += FFT_SIZE;
|
||||||
|
in += TONES;
|
||||||
|
d_offset = (d_offset + 1) % 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
dout << "OFDM PILOT: produced items: " << noutput_items << std::endl;
|
||||||
|
|
||||||
|
return noutput_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool d_debug;
|
||||||
|
int d_offset;
|
||||||
|
static const gr_complex POLARITY[127];
|
||||||
|
};
|
||||||
|
|
||||||
|
const gr_complex ofdm_pilot_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_pilot::sptr
|
||||||
|
ofdm_pilot::make(bool debug) {
|
||||||
|
return gnuradio::get_initial_sptr(new ofdm_pilot_impl(debug));
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* 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_preamble.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
|
||||||
|
class ofdm_preamble_impl : public ofdm_preamble {
|
||||||
|
|
||||||
|
static const int SYMBOL_LENGTH = 80;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ofdm_preamble_impl(bool debug) : block("ofdm_preamble",
|
||||||
|
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||||
|
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||||
|
d_debug(debug),
|
||||||
|
d_state(IDLE) {
|
||||||
|
|
||||||
|
set_relative_rate(1);
|
||||||
|
set_output_multiple(SYMBOL_LENGTH);
|
||||||
|
set_tag_propagation_policy(block::TPP_DONT);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ofdm_preamble_impl(){
|
||||||
|
}
|
||||||
|
|
||||||
|
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||||
|
gr_vector_const_void_star& input_items,
|
||||||
|
gr_vector_void_star& output_items) {
|
||||||
|
|
||||||
|
int ninput = ninput_items[0] / SYMBOL_LENGTH;
|
||||||
|
//assert(ninput_items[0] % SYMBOL_LENGTH == 0);
|
||||||
|
int noutput = noutput_items / SYMBOL_LENGTH;
|
||||||
|
|
||||||
|
const gr_complex *in = (const gr_complex*)input_items[0];
|
||||||
|
gr_complex *out = (gr_complex*)output_items[0];
|
||||||
|
|
||||||
|
int written = 0;
|
||||||
|
int consumed = 0;
|
||||||
|
|
||||||
|
const uint64_t nread = this->nitems_read(0);
|
||||||
|
std::vector<gr::tag_t> tags;
|
||||||
|
pmt::pmt_t key = pmt::string_to_symbol("tx_sob");
|
||||||
|
pmt::pmt_t srcid = pmt::string_to_symbol(this->name());
|
||||||
|
|
||||||
|
dout << "OFDM PREAMBLE: input size: " << ninput_items[0] << " output size: "
|
||||||
|
<< noutput_items << std::endl;
|
||||||
|
|
||||||
|
while(written < noutput) {
|
||||||
|
|
||||||
|
// debug
|
||||||
|
dout << "OFDM PREAMBLE: iteration - consumed: " << consumed <<
|
||||||
|
" written:" << written << std::endl;
|
||||||
|
//assert((consumed + 1) * SYMBOL_LENGTH <= ninput_items[0]);
|
||||||
|
|
||||||
|
switch(d_state) {
|
||||||
|
|
||||||
|
case IDLE:
|
||||||
|
|
||||||
|
if(consumed >= ninput) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dout << "OFDM PREAMBLE: start of new frame" << std::endl;
|
||||||
|
|
||||||
|
get_tags_in_range(tags, 0, nread + consumed * SYMBOL_LENGTH,
|
||||||
|
nread + (consumed + 1) * SYMBOL_LENGTH - 1,
|
||||||
|
pmt::string_to_symbol("ofdm_start"));
|
||||||
|
|
||||||
|
// looks like we changed to modulation scheme during the frame
|
||||||
|
if(tags.size() != 1) {
|
||||||
|
std::cout << "PREAMBLE: frame is longer than expected" << std::endl;
|
||||||
|
throw std::runtime_error("PREAMBLE: frame is too long");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d_frame_left = pmt::to_uint64(tags[0].value);
|
||||||
|
d_preamble_left = 4;
|
||||||
|
d_state = PRE;
|
||||||
|
|
||||||
|
// add tag to indicate start of odfm frame
|
||||||
|
add_item_tag(0, this->nitems_written(0) + written * SYMBOL_LENGTH, key, pmt::PMT_T, srcid);
|
||||||
|
|
||||||
|
// FALL THROUGH !!!!!
|
||||||
|
|
||||||
|
case PRE:
|
||||||
|
|
||||||
|
dout << "OFDM PREAMBLE: copy preamble" << std::endl;
|
||||||
|
|
||||||
|
memcpy(out, PREAMBLE + (4 - d_preamble_left) * SYMBOL_LENGTH,
|
||||||
|
SYMBOL_LENGTH * sizeof(gr_complex));
|
||||||
|
|
||||||
|
out += SYMBOL_LENGTH;
|
||||||
|
written++;
|
||||||
|
d_preamble_left--;
|
||||||
|
|
||||||
|
if(!d_preamble_left) {
|
||||||
|
d_state = FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FRAME:
|
||||||
|
if(consumed >= ninput) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dout << "OFDM PREAMBLE: copy frame" << std::endl;
|
||||||
|
|
||||||
|
memcpy(out, in, SYMBOL_LENGTH * sizeof(gr_complex));
|
||||||
|
|
||||||
|
consumed++;
|
||||||
|
in += SYMBOL_LENGTH;
|
||||||
|
out += SYMBOL_LENGTH;
|
||||||
|
written++;
|
||||||
|
d_frame_left--;
|
||||||
|
|
||||||
|
if(!d_frame_left) {
|
||||||
|
d_state = IDLE;
|
||||||
|
insert_eob(nitems_written(0) + written * SYMBOL_LENGTH -1);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
dout << "PREAMBLE: consumed " << consumed * SYMBOL_LENGTH;
|
||||||
|
dout << " written " << written * SYMBOL_LENGTH << std::endl;
|
||||||
|
consume(0, consumed * SYMBOL_LENGTH);
|
||||||
|
return written * SYMBOL_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_eob(uint64_t item) {
|
||||||
|
dout << "OFDM PAD: insert eob at: " << item << std::endl;
|
||||||
|
|
||||||
|
const pmt::pmt_t eob_key = pmt::string_to_symbol("tx_eob");
|
||||||
|
const pmt::pmt_t value = pmt::PMT_T;
|
||||||
|
const pmt::pmt_t srcid = pmt::string_to_symbol(this->name());
|
||||||
|
add_item_tag(0, item, eob_key, value, srcid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||||
|
{
|
||||||
|
if(d_state == PRE) {
|
||||||
|
ninput_items_required[0] = 0;
|
||||||
|
} else {
|
||||||
|
ninput_items_required[0] = noutput_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
dout << "forecast noutput_items: " << noutput_items << " required: " << ninput_items_required[0] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool d_debug;
|
||||||
|
size_t d_preamble_left;
|
||||||
|
size_t d_frame_left;
|
||||||
|
enum {IDLE, PRE, FRAME} d_state;
|
||||||
|
|
||||||
|
static gr_complex PREAMBLE[320];
|
||||||
|
};
|
||||||
|
|
||||||
|
ofdm_preamble::sptr
|
||||||
|
ofdm_preamble::make(bool debug) {
|
||||||
|
return gnuradio::get_initial_sptr(new ofdm_preamble_impl(debug));
|
||||||
|
}
|
||||||
|
|
||||||
|
gr_complex ofdm_preamble_impl::PREAMBLE[320] = {
|
||||||
|
gr_complex( 0.2041, 0.2041), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex(-1.1755, 0.0208), gr_complex(-0.1196, -0.6969), gr_complex( 1.2670, -0.1123),
|
||||||
|
gr_complex( 0.8165, 0.0000), gr_complex( 1.2670, -0.1123), gr_complex(-0.1196, -0.6969), gr_complex(-1.1755, 0.0208),
|
||||||
|
gr_complex( 0.4082, 0.4082), gr_complex( 0.0208, -1.1755), gr_complex(-0.6969, -0.1196), gr_complex(-0.1123, 1.2670),
|
||||||
|
gr_complex( 0.0000, 0.8165), gr_complex(-0.1123, 1.2670), gr_complex(-0.6969, -0.1196), gr_complex( 0.0208, -1.1755),
|
||||||
|
gr_complex(-0.4893, 0.2041), gr_complex( 0.1090, -0.8662), gr_complex( 0.8140, -0.9396), gr_complex(-0.8155, -1.0218),
|
||||||
|
gr_complex(-0.0249, -0.4773), gr_complex( 0.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470),
|
||||||
|
gr_complex(-0.3110, 1.3392), gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253),
|
||||||
|
gr_complex( 0.7297, -0.8197), gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728),
|
||||||
|
gr_complex( 0.5547, 0.5547), gr_complex( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326),
|
||||||
|
gr_complex( 0.2172, 0.5195), gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362),
|
||||||
|
gr_complex( 0.8657, 0.2298), gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784),
|
||||||
|
gr_complex( 0.1874, -0.2475), gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679),
|
||||||
|
gr_complex( 1.3868, 0.0000), gr_complex(-0.0455, -1.0679), gr_complex( 0.3528, -0.9865), gr_complex( 0.8594, 0.7348),
|
||||||
|
gr_complex( 0.1874, 0.2475), gr_complex( 0.5309, -0.7784), gr_complex(-1.0218, -0.4897), gr_complex(-0.3401, -0.9423),
|
||||||
|
gr_complex( 0.8657, -0.2298), gr_complex( 0.4734, 0.0362), gr_complex( 0.0088, -1.0207), gr_complex(-1.2142, -0.4205),
|
||||||
|
gr_complex( 0.2172, -0.5195), gr_complex( 0.5207, -0.1326), gr_complex(-0.1995, 1.4259), gr_complex( 1.0583, -0.0363),
|
||||||
|
gr_complex( 0.5547, -0.5547), gr_complex( 0.3277, 0.8728), gr_complex(-0.5077, 0.3488), gr_complex(-1.1650, 0.5789),
|
||||||
|
gr_complex( 0.7297, 0.8197), gr_complex( 0.6173, 0.1253), gr_complex(-0.5353, 0.7214), gr_complex(-0.5011, -0.1935),
|
||||||
|
gr_complex(-0.3110, -1.3392), gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), gr_complex( 0.6663, -0.6571),
|
||||||
|
gr_complex(-0.0249, 0.4773), gr_complex(-0.8155, 1.0218), gr_complex( 0.8140, 0.9396), gr_complex( 0.1090, 0.8662),
|
||||||
|
gr_complex(-1.3868, 0.0000), gr_complex( 0.1090, -0.8662), gr_complex( 0.8140, -0.9396), gr_complex(-0.8155, -1.0218),
|
||||||
|
gr_complex(-0.0249, -0.4773), gr_complex( 0.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470),
|
||||||
|
gr_complex(-0.3110, 1.3392), gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253),
|
||||||
|
gr_complex( 0.7297, -0.8197), gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728),
|
||||||
|
gr_complex( 0.5547, 0.5547), gr_complex( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326),
|
||||||
|
gr_complex( 0.2172, 0.5195), gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362),
|
||||||
|
gr_complex( 0.8657, 0.2298), gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784),
|
||||||
|
gr_complex( 0.1874, -0.2475), gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679),
|
||||||
|
gr_complex( 1.3868, 0.0000), gr_complex(-0.0455, -1.0679), gr_complex( 0.3528, -0.9865), gr_complex( 0.8594, 0.7348),
|
||||||
|
gr_complex( 0.1874, 0.2475), gr_complex( 0.5309, -0.7784), gr_complex(-1.0218, -0.4897), gr_complex(-0.3401, -0.9423),
|
||||||
|
gr_complex( 0.8657, -0.2298), gr_complex( 0.4734, 0.0362), gr_complex( 0.0088, -1.0207), gr_complex(-1.2142, -0.4205),
|
||||||
|
gr_complex( 0.2172, -0.5195), gr_complex( 0.5207, -0.1326), gr_complex(-0.1995, 1.4259), gr_complex( 1.0583, -0.0363),
|
||||||
|
gr_complex( 0.5547, -0.5547), gr_complex( 0.3277, 0.8728), gr_complex(-0.5077, 0.3488), gr_complex(-1.1650, 0.5789),
|
||||||
|
gr_complex( 0.7297, 0.8197), gr_complex( 0.6173, 0.1253), gr_complex(-0.5353, 0.7214), gr_complex(-0.5011, -0.1935),
|
||||||
|
gr_complex(-0.3110, -1.3392), gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), gr_complex( 0.6663, -0.6571),
|
||||||
|
gr_complex(-0.0249, 0.4773), gr_complex(-0.8155, 1.0218), gr_complex( 0.8140, 0.9396), gr_complex( 0.1090, 0.8662),
|
||||||
|
gr_complex(-1.3868, 0.0000), gr_complex( 0.1090, -0.8662), gr_complex( 0.8140, -0.9396), gr_complex(-0.8155, -1.0218),
|
||||||
|
gr_complex(-0.0249, -0.4773), gr_complex( 0.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470),
|
||||||
|
gr_complex(-0.3110, 1.3392), gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253),
|
||||||
|
gr_complex( 0.7297, -0.8197), gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728),
|
||||||
|
gr_complex( 0.5547, 0.5547), gr_complex( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326),
|
||||||
|
gr_complex( 0.2172, 0.5195), gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362),
|
||||||
|
gr_complex( 0.8657, 0.2298), gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784),
|
||||||
|
gr_complex( 0.1874, -0.2475), gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679)
|
||||||
|
};
|
||||||
+42
-36
@@ -15,40 +15,41 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <ieee802-11/ofdm_sync_long.h>
|
#include <ieee802-11/ofdm_sync_long.h>
|
||||||
|
#include "utils.h"
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
#include <gnuradio/filter/fir_filter.h>
|
#include <gnuradio/filter/fir_filter.h>
|
||||||
#include <gnuradio/fft/fft.h>
|
#include <gnuradio/fft/fft.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace gr::ieee802_11;
|
using namespace gr::ieee802_11;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
class ofdm_sync_long_impl : public ofdm_sync_long {
|
class ofdm_sync_long_impl : public ofdm_sync_long {
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_sync_long_impl(unsigned int sync_lenght, unsigned int freq_est, 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_log(log),
|
||||||
d_debug(debug),
|
d_debug(debug),
|
||||||
d_offset(0),
|
d_offset(0),
|
||||||
d_freq_est(0),
|
d_freq_est(0),
|
||||||
d_state(SYNC),
|
d_state(SYNC),
|
||||||
SYNC_LENGTH(sync_lenght),
|
SYNC_LENGTH(sync_length) {
|
||||||
FREQ_EST(freq_est) {
|
|
||||||
|
|
||||||
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_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;
|
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,
|
||||||
@@ -93,9 +94,8 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
|
|
||||||
while(i + 63 < ninput) {
|
while(i + 63 < ninput) {
|
||||||
|
|
||||||
if(d_offset < FREQ_EST) {
|
|
||||||
d_freq_est += in[i] * conj(in[i + 16]);
|
d_freq_est += in[i] * conj(in[i + 16]);
|
||||||
}
|
d_freq_est_buf[d_offset] = d_freq_est;
|
||||||
|
|
||||||
d_cor.push_back(std::tuple<double, int>(abs(d_correlation[i]), d_offset));
|
d_cor.push_back(std::tuple<double, int>(abs(d_correlation[i]), d_offset));
|
||||||
|
|
||||||
@@ -104,8 +104,12 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +164,7 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
std::runtime_error("bad state");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +177,8 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
|||||||
|
|
||||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required) {
|
void forecast (int noutput_items, gr_vector_int &ninput_items_required) {
|
||||||
|
|
||||||
|
// in sync state we need at least a symbol to correlate
|
||||||
|
// with the pattern
|
||||||
if(d_state == SYNC) {
|
if(d_state == SYNC) {
|
||||||
ninput_items_required[0] = 64;
|
ninput_items_required[0] = 64;
|
||||||
ninput_items_required[1] = 64;
|
ninput_items_required[1] = 64;
|
||||||
@@ -181,39 +187,38 @@ void forecast (int noutput_items, gr_vector_int &ninput_items_required) {
|
|||||||
ninput_items_required[0] = noutput_items;
|
ninput_items_required[0] = noutput_items;
|
||||||
ninput_items_required[1] = noutput_items;
|
ninput_items_required[1] = noutput_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
0 && dout << "LONG forecast noutput_items: " << noutput_items
|
|
||||||
<< " state: " << d_state
|
|
||||||
<< " req[0] " << ninput_items_required[0]
|
|
||||||
<< " req[1] " << ninput_items_required[1]
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void search_frame_start() {
|
void search_frame_start() {
|
||||||
|
|
||||||
|
// sort list (highest correlation first)
|
||||||
assert(d_cor.size() == SYNC_LENGTH);
|
assert(d_cor.size() == SYNC_LENGTH);
|
||||||
d_cor.sort();
|
d_cor.sort();
|
||||||
d_cor.reverse();
|
d_cor.reverse();
|
||||||
|
|
||||||
std::list<std::tuple<double, int>>::iterator it = d_cor.begin();
|
// copy list in vector for nicer access
|
||||||
|
vector<tuple<double, int>> vec(d_cor.begin(), d_cor.end());
|
||||||
int m1 = std::get<1>(*it);
|
|
||||||
it++;
|
|
||||||
int m2 = std::get<1>(*it);
|
|
||||||
it++;
|
|
||||||
int m3 = std::get<1>(*it);
|
|
||||||
int m = std::max(m1, std::max(m2, m3));
|
|
||||||
|
|
||||||
d_frame_start = m + 64;
|
|
||||||
|
|
||||||
dout << "d_frame_start " << d_frame_start << std::endl;
|
|
||||||
dout << "peaks " << m1 << " " << m2 << " " << m3 << std::endl;
|
|
||||||
|
|
||||||
//for(it = d_cor.begin(); it != d_cor.end(); it++) {
|
|
||||||
//std::cout << std::get<0>(*it) << " " << std::get<1>(*it) << std::endl;
|
|
||||||
//}
|
|
||||||
|
|
||||||
d_cor.clear();
|
d_cor.clear();
|
||||||
|
|
||||||
|
// in case we don't find anything use SYNC_LENGTH
|
||||||
|
d_frame_start = SYNC_LENGTH;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
for(int k = i + 1; k < 4; k++) {
|
||||||
|
int diff = abs(get<1>(vec[i]) - get<1>(vec[k]));
|
||||||
|
if(diff == 64) {
|
||||||
|
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64;
|
||||||
|
// nice match found, return immediately
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: check if these offsets make sense
|
||||||
|
} else if(diff == 63) {
|
||||||
|
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 63;
|
||||||
|
} else if(diff = 65) {
|
||||||
|
d_frame_start = max(get<1>(vec[i]), get<1>(vec[k])) + 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -222,20 +227,21 @@ private:
|
|||||||
int d_frame_start;
|
int d_frame_start;
|
||||||
gr_complex d_freq_est;
|
gr_complex d_freq_est;
|
||||||
gr_complex *d_correlation;
|
gr_complex *d_correlation;
|
||||||
|
gr_complex *d_freq_est_buf;
|
||||||
std::list<std::tuple<double, int>> d_cor;
|
std::list<std::tuple<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_debug;
|
const bool d_debug;
|
||||||
const int SYNC_LENGTH;
|
const int SYNC_LENGTH;
|
||||||
const int FREQ_EST;
|
|
||||||
|
|
||||||
static const std::vector<gr_complex> LONG;
|
static const std::vector<gr_complex> LONG;
|
||||||
};
|
};
|
||||||
|
|
||||||
ofdm_sync_long::sptr
|
ofdm_sync_long::sptr
|
||||||
ofdm_sync_long::make(unsigned int sync_length, unsigned int freq_est, bool debug) {
|
ofdm_sync_long::make(unsigned int sync_length, bool log, bool debug) {
|
||||||
return gnuradio::get_initial_sptr(new ofdm_sync_long_impl(sync_length, freq_est, debug));
|
return gnuradio::get_initial_sptr(new ofdm_sync_long_impl(sync_length, log, debug));
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<gr_complex> ofdm_sync_long_impl::LONG = {
|
const std::vector<gr_complex> ofdm_sync_long_impl::LONG = {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <ieee802-11/ofdm_sync_short.h>
|
#include <ieee802-11/ofdm_sync_short.h>
|
||||||
#include <gnuradio/io_signature.h>
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -23,13 +24,12 @@ using namespace gr::ieee802_11;
|
|||||||
|
|
||||||
class ofdm_sync_short_impl : public ofdm_sync_short {
|
class ofdm_sync_short_impl : public ofdm_sync_short {
|
||||||
|
|
||||||
#define dout d_debug && std::cout
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ofdm_sync_short_impl(double threshold, unsigned int max_samples,
|
ofdm_sync_short_impl(double threshold, unsigned int max_samples,
|
||||||
unsigned int min_plateau, bool debug) : block("ofdm_sync_short",
|
unsigned int min_plateau, bool log, bool debug) : block("ofdm_sync_short",
|
||||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(float)),
|
gr::io_signature::make2(2, 2, 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_debug(debug),
|
d_debug(debug),
|
||||||
d_state(SEARCH),
|
d_state(SEARCH),
|
||||||
d_plateau(0),
|
d_plateau(0),
|
||||||
@@ -108,7 +108,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void insert_tag(uint64_t item) {
|
void insert_tag(uint64_t item) {
|
||||||
dout << "SYNC SHORT: insert ofdm_start at: " << item << std::endl;
|
mylog(boost::format("frame start at %1%") % item);
|
||||||
|
|
||||||
const pmt::pmt_t key = pmt::string_to_symbol("ofdm_start");
|
const pmt::pmt_t key = pmt::string_to_symbol("ofdm_start");
|
||||||
const pmt::pmt_t value = pmt::PMT_T;
|
const pmt::pmt_t value = pmt::PMT_T;
|
||||||
@@ -121,6 +121,7 @@ private:
|
|||||||
int d_copy_left;
|
int d_copy_left;
|
||||||
int d_plateau;
|
int d_plateau;
|
||||||
const double d_threshold;
|
const double d_threshold;
|
||||||
|
const bool d_log;
|
||||||
const bool d_debug;
|
const bool d_debug;
|
||||||
const unsigned int MAX_SAMPLES;
|
const unsigned int MAX_SAMPLES;
|
||||||
const unsigned int MIN_PLATEAU;
|
const unsigned int MIN_PLATEAU;
|
||||||
@@ -128,7 +129,7 @@ private:
|
|||||||
|
|
||||||
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 max_samples,
|
||||||
unsigned int min_plateau, bool debug) {
|
unsigned int min_plateau, bool log, bool debug) {
|
||||||
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold,
|
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold,
|
||||||
max_samples, min_plateau, debug));
|
max_samples, min_plateau, log, debug));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +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 "ofdm_utils.h"
|
|
||||||
|
|
||||||
#include <boost/crc.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
|
|
||||||
ofdm_param::ofdm_param(ENCODING e) {
|
|
||||||
encoding = e;
|
|
||||||
|
|
||||||
switch(e) {
|
|
||||||
case BPSK_1_2:
|
|
||||||
n_bpsc = 1;
|
|
||||||
n_cbps = 48;
|
|
||||||
n_dbps = 24;
|
|
||||||
rate_field = 0x0D; // 0b00001101
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BPSK_3_4:
|
|
||||||
n_bpsc = 1;
|
|
||||||
n_cbps = 48;
|
|
||||||
n_dbps = 36;
|
|
||||||
rate_field = 0x0F; // 0b00001111
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QPSK_1_2:
|
|
||||||
n_bpsc = 2;
|
|
||||||
n_cbps = 96;
|
|
||||||
n_dbps = 48;
|
|
||||||
rate_field = 0x05; // 0b00000101
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QPSK_3_4:
|
|
||||||
n_bpsc = 2;
|
|
||||||
n_cbps = 96;
|
|
||||||
n_dbps = 72;
|
|
||||||
rate_field = 0x07; // 0b00000111
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QAM16_1_2:
|
|
||||||
n_bpsc = 4;
|
|
||||||
n_cbps = 192;
|
|
||||||
n_dbps = 96;
|
|
||||||
rate_field = 0x09; // 0b00001001
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QAM16_3_4:
|
|
||||||
n_bpsc = 4;
|
|
||||||
n_cbps = 192;
|
|
||||||
n_dbps = 144;
|
|
||||||
rate_field = 0x0B; // 0b00001011
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QAM64_2_3:
|
|
||||||
n_bpsc = 6;
|
|
||||||
n_cbps = 288;
|
|
||||||
n_dbps = 192;
|
|
||||||
rate_field = 0x01; // 0b00000001
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QAM64_3_4:
|
|
||||||
n_bpsc = 6;
|
|
||||||
n_cbps = 288;
|
|
||||||
n_dbps = 216;
|
|
||||||
rate_field = 0x03; // 0b00000011
|
|
||||||
break;
|
|
||||||
defaut:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ofdm_param::print_out() {
|
|
||||||
std::cout << "OFDM Parameters:" << std::endl;
|
|
||||||
std::cout << "endcoding :" << encoding << std::endl;
|
|
||||||
std::cout << "rate_field :" << (int)rate_field << std::endl;
|
|
||||||
std::cout << "n_bpsc :" << n_bpsc << std::endl;
|
|
||||||
std::cout << "n_cbps :" << n_cbps << std::endl;
|
|
||||||
std::cout << "n_dbps :" << n_dbps << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx_param::tx_param(ofdm_param &ofdm, int psdu_length) {
|
|
||||||
|
|
||||||
psdu_size = psdu_length;
|
|
||||||
|
|
||||||
// number of symbols (17-11)
|
|
||||||
n_sym = (int) ceil((16 + 8 * psdu_size + 6) / (double) ofdm.n_dbps);
|
|
||||||
|
|
||||||
// number of bits of the data field (17-12)
|
|
||||||
n_data = n_sym * ofdm.n_dbps;
|
|
||||||
|
|
||||||
// number of padding bits (17-13)
|
|
||||||
n_pad = n_data - (16 + 8 * psdu_size + 6);
|
|
||||||
|
|
||||||
n_encoded_bits = n_sym * ofdm.n_cbps;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
tx_param::print_out() {
|
|
||||||
std::cout << "TX Parameters:" << std::endl;
|
|
||||||
std::cout << "psdu_size: " << psdu_size << std::endl;
|
|
||||||
std::cout << "n_sym: " << n_sym << std::endl;
|
|
||||||
std::cout << "n_data: " << n_data << std::endl;
|
|
||||||
std::cout << "n_pad: " << n_pad << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,88 +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/>.
|
|
||||||
*/
|
|
||||||
#ifndef INCLUDED_IEEE802_11_OFDM_UTILS_H
|
|
||||||
#define INCLUDED_IEEE802_11_OFDM_UTILS_H
|
|
||||||
|
|
||||||
#include <ieee802-11/api.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define structure for the MAC header of a data frame.
|
|
||||||
* Values as stored as MSB, but standard mandates LSB
|
|
||||||
* representation. Bit utils functions can help changing
|
|
||||||
* endiannes
|
|
||||||
*/
|
|
||||||
struct MAC_DATAFRAME_HEADER {
|
|
||||||
char frame_control[2]; //protocol version, type, subtype, to_ds, from_ds, ...
|
|
||||||
char duration[2]; //duration field
|
|
||||||
char address1[6]; //address 1 indicating BSSID: 6 bytes MAC address
|
|
||||||
char address2[6]; //address 2 indicating receiver
|
|
||||||
char address3[6]; //address 3 indicating sender
|
|
||||||
char sequence[2]; //sequence number plus fragment number
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ENCODING {
|
|
||||||
BPSK_1_2 = 0,
|
|
||||||
BPSK_3_4 = 1,
|
|
||||||
QPSK_1_2 = 2,
|
|
||||||
QPSK_3_4 = 3,
|
|
||||||
QAM16_1_2 = 4,
|
|
||||||
QAM16_3_4 = 5,
|
|
||||||
QAM64_2_3 = 6,
|
|
||||||
QAM64_3_4 = 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OFDM parameters
|
|
||||||
*/
|
|
||||||
class ofdm_param {
|
|
||||||
public:
|
|
||||||
ofdm_param(ENCODING e);
|
|
||||||
|
|
||||||
// data rate
|
|
||||||
ENCODING encoding;
|
|
||||||
// rate field of the SIGNAL header
|
|
||||||
char rate_field;
|
|
||||||
// number of coded bits per sub carrier
|
|
||||||
int n_bpsc;
|
|
||||||
// number of coded bits per OFDM symbol
|
|
||||||
int n_cbps;
|
|
||||||
// number of data bits per OFDM symbol
|
|
||||||
int n_dbps;
|
|
||||||
|
|
||||||
void print_out();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* packet specific parameters
|
|
||||||
*/
|
|
||||||
class tx_param {
|
|
||||||
public:
|
|
||||||
tx_param(ofdm_param &ofdm, int psdu_length);
|
|
||||||
// PSDU size in bytes
|
|
||||||
int psdu_size;
|
|
||||||
// number of OFDM symbols (17-11)
|
|
||||||
int n_sym;
|
|
||||||
// number of data bits in the DATA field, including service and padding (17-12)
|
|
||||||
int n_data;
|
|
||||||
// number of padding bits in the DATA field (17-13)
|
|
||||||
int n_pad;
|
|
||||||
int n_encoded_bits;
|
|
||||||
|
|
||||||
void print_out();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* INCLUDED_IEEE802_11_OFDM_UTILS_H */
|
|
||||||
+343
@@ -0,0 +1,343 @@
|
|||||||
|
/*
|
||||||
|
* 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 "utils.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
ofdm_param::ofdm_param(Encoding e) {
|
||||||
|
encoding = e;
|
||||||
|
|
||||||
|
switch(e) {
|
||||||
|
case BPSK_1_2:
|
||||||
|
n_bpsc = 1;
|
||||||
|
n_cbps = 48;
|
||||||
|
n_dbps = 24;
|
||||||
|
rate_field = 0x0D; // 0b00001101
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BPSK_3_4:
|
||||||
|
n_bpsc = 1;
|
||||||
|
n_cbps = 48;
|
||||||
|
n_dbps = 36;
|
||||||
|
rate_field = 0x0F; // 0b00001111
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QPSK_1_2:
|
||||||
|
n_bpsc = 2;
|
||||||
|
n_cbps = 96;
|
||||||
|
n_dbps = 48;
|
||||||
|
rate_field = 0x05; // 0b00000101
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QPSK_3_4:
|
||||||
|
n_bpsc = 2;
|
||||||
|
n_cbps = 96;
|
||||||
|
n_dbps = 72;
|
||||||
|
rate_field = 0x07; // 0b00000111
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM16_1_2:
|
||||||
|
n_bpsc = 4;
|
||||||
|
n_cbps = 192;
|
||||||
|
n_dbps = 96;
|
||||||
|
rate_field = 0x09; // 0b00001001
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM16_3_4:
|
||||||
|
n_bpsc = 4;
|
||||||
|
n_cbps = 192;
|
||||||
|
n_dbps = 144;
|
||||||
|
rate_field = 0x0B; // 0b00001011
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM64_2_3:
|
||||||
|
n_bpsc = 6;
|
||||||
|
n_cbps = 288;
|
||||||
|
n_dbps = 192;
|
||||||
|
rate_field = 0x01; // 0b00000001
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM64_3_4:
|
||||||
|
n_bpsc = 6;
|
||||||
|
n_cbps = 288;
|
||||||
|
n_dbps = 216;
|
||||||
|
rate_field = 0x03; // 0b00000011
|
||||||
|
break;
|
||||||
|
defaut:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ofdm_param::print_out() {
|
||||||
|
std::cout << "OFDM Parameters:" << std::endl;
|
||||||
|
std::cout << "endcoding :" << encoding << std::endl;
|
||||||
|
std::cout << "rate_field :" << (int)rate_field << std::endl;
|
||||||
|
std::cout << "n_bpsc :" << n_bpsc << std::endl;
|
||||||
|
std::cout << "n_cbps :" << n_cbps << std::endl;
|
||||||
|
std::cout << "n_dbps :" << n_dbps << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_param::tx_param(ofdm_param &ofdm, int psdu_length) {
|
||||||
|
|
||||||
|
psdu_size = psdu_length;
|
||||||
|
|
||||||
|
// number of symbols (17-11)
|
||||||
|
n_sym = (int) ceil((16 + 8 * psdu_size + 6) / (double) ofdm.n_dbps);
|
||||||
|
|
||||||
|
// number of bits of the data field (17-12)
|
||||||
|
n_data = n_sym * ofdm.n_dbps;
|
||||||
|
|
||||||
|
// number of padding bits (17-13)
|
||||||
|
n_pad = n_data - (16 + 8 * psdu_size + 6);
|
||||||
|
|
||||||
|
n_encoded_bits = n_sym * ofdm.n_cbps;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
tx_param::print_out() {
|
||||||
|
std::cout << "TX Parameters:" << std::endl;
|
||||||
|
std::cout << "psdu_size: " << psdu_size << std::endl;
|
||||||
|
std::cout << "n_sym: " << n_sym << std::endl;
|
||||||
|
std::cout << "n_data: " << n_data << std::endl;
|
||||||
|
std::cout << "n_pad: " << n_pad << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_bit(int b, int i) {
|
||||||
|
return (b & (1 << i) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scramble(const char *in, char *out, tx_param &tx, char initial_state) {
|
||||||
|
|
||||||
|
int state = initial_state;
|
||||||
|
int feedback;
|
||||||
|
|
||||||
|
for (int i = 0; i < tx.n_data; i++) {
|
||||||
|
|
||||||
|
feedback = (!!(state & 64)) ^ (!!(state & 8));
|
||||||
|
out[i] = feedback ^ in[i];
|
||||||
|
state = ((state << 1) & 0x7e) | feedback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_tail_bits(char *scrambled_data, tx_param &tx) {
|
||||||
|
memset(scrambled_data + tx.n_data - tx.n_pad - 6, 0, 6 * sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ones(int n) {
|
||||||
|
int sum = 0;
|
||||||
|
for(int i = 0; i < 8; i++) {
|
||||||
|
if(n & (1 << i)) {
|
||||||
|
sum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void convolutional_encoding(const char *in, char *out, tx_param &tx) {
|
||||||
|
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < tx.n_data; i++) {
|
||||||
|
assert(in[i] == 0 || in[i] == 1);
|
||||||
|
state = ((state << 1) & 0x7e) | in[i];
|
||||||
|
out[i * 2] = ones(state & 0155) % 2;
|
||||||
|
out[i * 2 + 1] = ones(state & 0117) % 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void puncturing(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||||
|
|
||||||
|
int mod;
|
||||||
|
|
||||||
|
for (int i = 0; i < tx.n_data * 2; i++) {
|
||||||
|
switch(ofdm.encoding) {
|
||||||
|
case BPSK_1_2:
|
||||||
|
case QPSK_1_2:
|
||||||
|
case QAM16_1_2:
|
||||||
|
*out = in[i];
|
||||||
|
out++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QAM64_2_3:
|
||||||
|
if (i % 4 != 3) {
|
||||||
|
*out = in[i];
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BPSK_3_4:
|
||||||
|
case QPSK_3_4:
|
||||||
|
case QAM16_3_4:
|
||||||
|
case QAM64_3_4:
|
||||||
|
mod = i % 6;
|
||||||
|
if (!(mod == 3 || mod == 4)) {
|
||||||
|
*out = in[i];
|
||||||
|
out++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
defaut:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void interleave(const char *in, char *out, tx_param &tx, ofdm_param &ofdm, bool reverse) {
|
||||||
|
|
||||||
|
int n_cbps = ofdm.n_cbps;
|
||||||
|
int first[n_cbps];
|
||||||
|
int second[n_cbps];
|
||||||
|
int s = std::max(ofdm.n_bpsc / 2, 1);
|
||||||
|
|
||||||
|
for(int j = 0; j < n_cbps; j++) {
|
||||||
|
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < n_cbps; i++) {
|
||||||
|
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 k = 0; k < n_cbps; k++) {
|
||||||
|
if(reverse) {
|
||||||
|
out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k];
|
||||||
|
} else {
|
||||||
|
out[i * n_cbps + k] = in[i * n_cbps + second[first[k]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void interleave(const double *in, double *out, tx_param &tx, ofdm_param &ofdm, bool reverse) {
|
||||||
|
|
||||||
|
int n_cbps = ofdm.n_cbps;
|
||||||
|
int first[n_cbps];
|
||||||
|
int second[n_cbps];
|
||||||
|
int s = std::max(ofdm.n_bpsc / 2, 1);
|
||||||
|
|
||||||
|
for(int j = 0; j < n_cbps; j++) {
|
||||||
|
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < n_cbps; i++) {
|
||||||
|
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 k = 0; k < n_cbps; k++) {
|
||||||
|
if(reverse) {
|
||||||
|
out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k];
|
||||||
|
} else {
|
||||||
|
out[i * n_cbps + k] = in[i * n_cbps + second[first[k]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void split_symbols(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||||
|
|
||||||
|
int symbols = tx.n_sym * 48;
|
||||||
|
|
||||||
|
for (int i = 0; i < symbols; i++) {
|
||||||
|
out[i] = 0;
|
||||||
|
for(int k = 0; k < ofdm.n_bpsc; k++) {
|
||||||
|
assert(*in == 1 || *in == 0);
|
||||||
|
out[i] |= (*in << (ofdm.n_bpsc - k - 1));
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void generate_signal_field(char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||||
|
|
||||||
|
//data bits of the signal header
|
||||||
|
char *signal_header = (char *) malloc(sizeof(char) * 24);
|
||||||
|
|
||||||
|
//signal header after...
|
||||||
|
//convolutional encoding
|
||||||
|
char *encoded_signal_header = (char *) malloc(sizeof(char) * 48);
|
||||||
|
//interleaving
|
||||||
|
char *interleaved_signal_header = (char *) malloc(sizeof(char) * 48);
|
||||||
|
|
||||||
|
int length = tx.psdu_size;
|
||||||
|
|
||||||
|
// first 4 bits represent the modulation and coding scheme
|
||||||
|
signal_header[ 0] = get_bit(ofdm.rate_field, 3);
|
||||||
|
signal_header[ 1] = get_bit(ofdm.rate_field, 2);
|
||||||
|
signal_header[ 2] = get_bit(ofdm.rate_field, 1);
|
||||||
|
signal_header[ 3] = get_bit(ofdm.rate_field, 0);
|
||||||
|
// 5th bit is reserved and must be set to 0
|
||||||
|
signal_header[ 4] = 0;
|
||||||
|
// then 12 bits represent the length
|
||||||
|
signal_header[ 5] = get_bit(length, 0);
|
||||||
|
signal_header[ 6] = get_bit(length, 1);
|
||||||
|
signal_header[ 7] = get_bit(length, 2);
|
||||||
|
signal_header[ 8] = get_bit(length, 3);
|
||||||
|
signal_header[ 9] = get_bit(length, 4);
|
||||||
|
signal_header[10] = get_bit(length, 5);
|
||||||
|
signal_header[11] = get_bit(length, 6);
|
||||||
|
signal_header[12] = get_bit(length, 7);
|
||||||
|
signal_header[13] = get_bit(length, 8);
|
||||||
|
signal_header[14] = get_bit(length, 9);
|
||||||
|
signal_header[15] = get_bit(length, 10);
|
||||||
|
signal_header[16] = get_bit(length, 11);
|
||||||
|
//18-th bit is the parity bit for the first 17 bits
|
||||||
|
int sum = 0;
|
||||||
|
for(int i = 0; i < 17; i++) {
|
||||||
|
if(signal_header[i]) {
|
||||||
|
sum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signal_header[17] = sum % 2;
|
||||||
|
|
||||||
|
// last 6 bits must be set to 0
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
signal_header[18 + i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofdm_param signal_ofdm(BPSK_1_2);
|
||||||
|
tx_param signal_tx(signal_ofdm, 3);
|
||||||
|
signal_tx.n_data = 24;
|
||||||
|
signal_tx.n_sym = 1;
|
||||||
|
|
||||||
|
// convolutional encoding (scrambling is not needed)
|
||||||
|
convolutional_encoding(signal_header, encoded_signal_header, signal_tx);
|
||||||
|
// interleaving
|
||||||
|
//interleave(encoded_signal_header, interleaved_signal_header, signal_tx, signal_ofdm);
|
||||||
|
interleave(encoded_signal_header, out, signal_tx, signal_ofdm);
|
||||||
|
|
||||||
|
free(signal_header);
|
||||||
|
free(encoded_signal_header);
|
||||||
|
free(interleaved_signal_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_bits(const char *psdu, char *data_bits, tx_param &tx) {
|
||||||
|
|
||||||
|
// first 16 bits are zero (SERVICE/DATA field)
|
||||||
|
memset(data_bits, 0, 16);
|
||||||
|
data_bits += 16;
|
||||||
|
|
||||||
|
for(int i = 0; i < tx.psdu_size; i++) {
|
||||||
|
for(int b = 0; b < 8; b++) {
|
||||||
|
data_bits[i * 8 + b] = !!(psdu[i] & (1 << b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_OFDM_UTILS_H
|
||||||
|
#define INCLUDED_IEEE802_11_OFDM_UTILS_H
|
||||||
|
|
||||||
|
#include <ieee802-11/api.h>
|
||||||
|
#include <ieee802-11/ofdm_mapper.h>
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define dout d_debug && std::cout
|
||||||
|
#define mylog(msg) do { if(d_log) *d_logger << log4cpp::Priority::INFO << msg << log4cpp::eol; } while(0);
|
||||||
|
|
||||||
|
struct MAC_DATAFRAME_HEADER {
|
||||||
|
//protocol version, type, subtype, to_ds, from_ds, ...
|
||||||
|
char frame_control[2];
|
||||||
|
char duration[2];
|
||||||
|
char address1[6];
|
||||||
|
char address2[6];
|
||||||
|
char address3[6];
|
||||||
|
uint16_t sequence;
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OFDM parameters
|
||||||
|
*/
|
||||||
|
class ofdm_param {
|
||||||
|
public:
|
||||||
|
ofdm_param(Encoding e);
|
||||||
|
|
||||||
|
// data rate
|
||||||
|
Encoding encoding;
|
||||||
|
// rate field of the SIGNAL header
|
||||||
|
char rate_field;
|
||||||
|
// number of coded bits per sub carrier
|
||||||
|
int n_bpsc;
|
||||||
|
// number of coded bits per OFDM symbol
|
||||||
|
int n_cbps;
|
||||||
|
// number of data bits per OFDM symbol
|
||||||
|
int n_dbps;
|
||||||
|
|
||||||
|
void print_out();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packet specific parameters
|
||||||
|
*/
|
||||||
|
class tx_param {
|
||||||
|
public:
|
||||||
|
tx_param(ofdm_param &ofdm, int psdu_length);
|
||||||
|
// PSDU size in bytes
|
||||||
|
int psdu_size;
|
||||||
|
// number of OFDM symbols (17-11)
|
||||||
|
int n_sym;
|
||||||
|
// number of data bits in the DATA field, including service and padding (17-12)
|
||||||
|
int n_data;
|
||||||
|
// number of padding bits in the DATA field (17-13)
|
||||||
|
int n_pad;
|
||||||
|
int n_encoded_bits;
|
||||||
|
|
||||||
|
void print_out();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a payload, generates a MAC data frame (i.e., a PSDU) to be given
|
||||||
|
* to the physical layer for encoding.
|
||||||
|
*
|
||||||
|
* \param msdu the payload for the MAC frame
|
||||||
|
* \param msdu_size the size of the msdu in bytes
|
||||||
|
* \param psdu pointer to a byte array where to store the MAC frame. Memory
|
||||||
|
* will be alloced by the function
|
||||||
|
* \param psdu_size pointer to an integer where the size of the psdu in bytes
|
||||||
|
* will be stored
|
||||||
|
* \param seq sequence number of the frame
|
||||||
|
*/
|
||||||
|
void generate_mac_data_frame(const char *msdu, int msdu_size, char **psdu, int *psdu_size, char seq);
|
||||||
|
|
||||||
|
|
||||||
|
void scramble(const char *input, char *out, tx_param &tx, char initial_state);
|
||||||
|
|
||||||
|
void reset_tail_bits(char *scrambled_data, tx_param &tx);
|
||||||
|
|
||||||
|
void convolutional_encoding(const char *input, char *out, tx_param &tx);
|
||||||
|
|
||||||
|
void puncturing(const char *input, char *out, tx_param &tx, ofdm_param &ofdm);
|
||||||
|
|
||||||
|
void interleave(const char *input, char *out, tx_param &tx, ofdm_param &ofdm, bool reverse = false);
|
||||||
|
void interleave(const double *input, double *out, tx_param &tx, ofdm_param &ofdm, bool reverse = false);
|
||||||
|
|
||||||
|
void split_symbols(const char *input, char *out, tx_param &tx, ofdm_param &ofdm);
|
||||||
|
|
||||||
|
void generate_signal_field(char *out, tx_param &tx, ofdm_param &ofdm);
|
||||||
|
|
||||||
|
void generate_bits(const char *psdu, char *data_bits, tx_param &tx);
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_OFDM_UTILS_H */
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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 "wave_llc_impl.h"
|
||||||
|
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <gnuradio/block_detail.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
wave_llc_impl::wave_llc_impl() :
|
||||||
|
block("wave_llc",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0)) {
|
||||||
|
|
||||||
|
message_port_register_out(pmt::mp("out"));
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("in"));
|
||||||
|
set_msg_handler(pmt::mp("in"), boost::bind(&wave_llc_impl::make_frame, this, _1));
|
||||||
|
|
||||||
|
d_header[0] = 0xaa;
|
||||||
|
d_header[1] = 0xaa;
|
||||||
|
d_header[2] = 0x03;
|
||||||
|
d_header[3] = 0x00;
|
||||||
|
d_header[4] = 0x00;
|
||||||
|
d_header[5] = 0x00;
|
||||||
|
d_header[6] = 0x88;
|
||||||
|
d_header[7] = 0xdc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wave_llc_impl::make_frame (pmt::pmt_t msg) {
|
||||||
|
|
||||||
|
if(pmt::is_eof_object(msg)) {
|
||||||
|
message_port_pub(pmt::mp("out"), pmt::PMT_EOF);
|
||||||
|
detail().get()->set_done(true);
|
||||||
|
return;
|
||||||
|
} else if(pmt::is_pair(msg)) {
|
||||||
|
msg = pmt::cdr(msg);
|
||||||
|
} else if(pmt::is_blob(msg)) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw std::invalid_argument("wave_llc expects PDU or blob input");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t data_len = pmt::blob_length(msg);
|
||||||
|
|
||||||
|
char *buf = reinterpret_cast<char *>(std::malloc(
|
||||||
|
sizeof(d_header) + data_len));
|
||||||
|
|
||||||
|
std::memcpy(buf, d_header, sizeof(d_header));
|
||||||
|
std::memcpy(buf + sizeof(d_header), pmt::blob_data(msg), data_len);
|
||||||
|
|
||||||
|
pmt::pmt_t llc_msg = pmt::make_blob(buf, sizeof(d_header) + data_len);
|
||||||
|
message_port_pub(pmt::mp("out"), llc_msg);
|
||||||
|
|
||||||
|
std::free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
wave_llc::sptr
|
||||||
|
wave_llc::make() {
|
||||||
|
return gnuradio::get_initial_sptr(new wave_llc_impl());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_WAVE_LLC_IMPL_H
|
||||||
|
#define INCLUDED_IEEE802_11_WAVE_LLC_IMPL_H
|
||||||
|
|
||||||
|
#include <ieee802-11/wave_llc.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
class wave_llc_impl : public wave_llc {
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
wave_llc_impl();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void make_frame (pmt::pmt_t msg);
|
||||||
|
|
||||||
|
char d_header[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_WAVE_LLC_IMPL_H */
|
||||||
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* 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 "wave_short_message_impl.h"
|
||||||
|
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <gnuradio/block_detail.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
using namespace gr::ieee802_11;
|
||||||
|
|
||||||
|
wave_short_message_impl::wave_short_message_impl(int version) :
|
||||||
|
block("wave_short_message",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_version(version) {
|
||||||
|
|
||||||
|
message_port_register_out(pmt::mp("out"));
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("in"));
|
||||||
|
set_msg_handler(pmt::mp("in"), boost::bind(&wave_short_message_impl::make_frame, this, _1));
|
||||||
|
|
||||||
|
|
||||||
|
hdr0.version = 0x00;
|
||||||
|
hdr0.security = 0x00;
|
||||||
|
hdr0.channel = 0x04;
|
||||||
|
hdr0.rate = 0x01;
|
||||||
|
hdr0.power = 0x40;
|
||||||
|
hdr0.app_class = 0x00;
|
||||||
|
hdr0.acm_length = 0x00;
|
||||||
|
|
||||||
|
|
||||||
|
hdr2.version = 0x02;
|
||||||
|
hdr2.psid = 0x55;
|
||||||
|
hdr2.wsm_id = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wave_short_message_impl::make_frame (pmt::pmt_t msg) {
|
||||||
|
|
||||||
|
if(pmt::is_eof_object(msg)) {
|
||||||
|
message_port_pub(pmt::mp("out"), pmt::PMT_EOF);
|
||||||
|
detail().get()->set_done(true);
|
||||||
|
return;
|
||||||
|
} else if(pmt::is_symbol(msg)) {
|
||||||
|
std::string s = pmt::symbol_to_string(msg);
|
||||||
|
msg = pmt::make_blob(s.data(), s.size());
|
||||||
|
} else if(!pmt::is_blob(msg)) {
|
||||||
|
throw std::invalid_argument("WSM input has to be a blob");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t data_len = pmt::blob_length(msg);
|
||||||
|
|
||||||
|
pmt::pmt_t wsm;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
switch(d_version) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
hdr0.length = data_len;
|
||||||
|
buf = reinterpret_cast<char*>(std::malloc(data_len + sizeof(wave_hdr_v0)));
|
||||||
|
|
||||||
|
std::memcpy(buf, &hdr0, sizeof(wave_hdr_v0));
|
||||||
|
std::memcpy(buf + sizeof(wave_hdr_v0), pmt::blob_data(msg), data_len);
|
||||||
|
|
||||||
|
wsm = pmt::make_blob(buf, data_len + sizeof(wave_hdr_v0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
hdr2.length = (data_len << 8) + (data_len >> 8);
|
||||||
|
buf = reinterpret_cast<char*>(std::malloc(data_len + sizeof(wave_hdr_v2)));
|
||||||
|
|
||||||
|
std::memcpy(buf, &hdr2, sizeof(wave_hdr_v2));
|
||||||
|
std::memcpy(buf + sizeof(wave_hdr_v2), pmt::blob_data(msg), data_len);
|
||||||
|
|
||||||
|
wsm = pmt::make_blob(buf, data_len + sizeof(wave_hdr_v2));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("wrong version of WSM set");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::free(buf);
|
||||||
|
message_port_pub(pmt::mp("out"), wsm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wave_short_message_impl::set_version(int version) {
|
||||||
|
if(!(version == 0 || version == 2)) {
|
||||||
|
throw std::invalid_argument("wrong version of WSM set");
|
||||||
|
}
|
||||||
|
d_version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
wave_short_message::sptr
|
||||||
|
wave_short_message::make(int version) {
|
||||||
|
return gnuradio::get_initial_sptr(new wave_short_message_impl(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_IEEE802_11_WAVE_SHORT_MESSAGE_IMPL_H
|
||||||
|
#define INCLUDED_IEEE802_11_WAVE_SHORT_MESSAGE_IMPL_H
|
||||||
|
|
||||||
|
#include <ieee802-11/wave_short_message.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace ieee802_11 {
|
||||||
|
|
||||||
|
struct wave_hdr_v0 {
|
||||||
|
uint8_t version;
|
||||||
|
uint8_t security;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t rate;
|
||||||
|
uint8_t power;
|
||||||
|
uint8_t app_class;
|
||||||
|
uint8_t acm_length;
|
||||||
|
uint16_t length;
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
struct wave_hdr_v2 {
|
||||||
|
uint8_t version;
|
||||||
|
uint8_t psid;
|
||||||
|
uint8_t wsm_id;
|
||||||
|
uint16_t length;
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
class wave_short_message_impl : public wave_short_message {
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
wave_short_message_impl(int version);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void make_frame (pmt::pmt_t msg);
|
||||||
|
void set_version(int version);
|
||||||
|
|
||||||
|
wave_hdr_v0 hdr0;
|
||||||
|
wave_hdr_v2 hdr2;
|
||||||
|
int d_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ieee802_11
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_IEEE802_11_WAVE_SHORT_MESSAGE_IMPL_H */
|
||||||
|
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2004,2009,2012 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""Misc utilities used at build time
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re, os, os.path
|
||||||
|
from build_utils_codes import *
|
||||||
|
|
||||||
|
|
||||||
|
# set srcdir to the directory that contains Makefile.am
|
||||||
|
try:
|
||||||
|
srcdir = os.environ['srcdir']
|
||||||
|
except KeyError, e:
|
||||||
|
srcdir = "."
|
||||||
|
srcdir = srcdir + '/'
|
||||||
|
|
||||||
|
# set do_makefile to either true or false dependeing on the environment
|
||||||
|
try:
|
||||||
|
if os.environ['do_makefile'] == '0':
|
||||||
|
do_makefile = False
|
||||||
|
else:
|
||||||
|
do_makefile = True
|
||||||
|
except KeyError, e:
|
||||||
|
do_makefile = False
|
||||||
|
|
||||||
|
# set do_sources to either true or false dependeing on the environment
|
||||||
|
try:
|
||||||
|
if os.environ['do_sources'] == '0':
|
||||||
|
do_sources = False
|
||||||
|
else:
|
||||||
|
do_sources = True
|
||||||
|
except KeyError, e:
|
||||||
|
do_sources = True
|
||||||
|
|
||||||
|
name_dict = {}
|
||||||
|
|
||||||
|
def log_output_name (name):
|
||||||
|
(base, ext) = os.path.splitext (name)
|
||||||
|
ext = ext[1:] # drop the leading '.'
|
||||||
|
|
||||||
|
entry = name_dict.setdefault (ext, [])
|
||||||
|
entry.append (name)
|
||||||
|
|
||||||
|
def open_and_log_name (name, dir):
|
||||||
|
global do_sources
|
||||||
|
if do_sources:
|
||||||
|
f = open (name, dir)
|
||||||
|
else:
|
||||||
|
f = None
|
||||||
|
log_output_name (name)
|
||||||
|
return f
|
||||||
|
|
||||||
|
def expand_template (d, template_filename, extra = ""):
|
||||||
|
'''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file
|
||||||
|
'''
|
||||||
|
global do_sources
|
||||||
|
output_extension = extract_extension (template_filename)
|
||||||
|
template = open_src (template_filename, 'r')
|
||||||
|
output_name = d['NAME'] + extra + '.' + output_extension
|
||||||
|
log_output_name (output_name)
|
||||||
|
if do_sources:
|
||||||
|
output = open (output_name, 'w')
|
||||||
|
do_substitution (d, template, output)
|
||||||
|
output.close ()
|
||||||
|
template.close ()
|
||||||
|
|
||||||
|
def output_glue (dirname):
|
||||||
|
output_makefile_fragment ()
|
||||||
|
output_ifile_include (dirname)
|
||||||
|
|
||||||
|
def output_makefile_fragment ():
|
||||||
|
global do_makefile
|
||||||
|
if not do_makefile:
|
||||||
|
return
|
||||||
|
# overwrite the source, which must be writable; this should have been
|
||||||
|
# checked for beforehand in the top-level Makefile.gen.gen .
|
||||||
|
f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w')
|
||||||
|
f.write ('#\n# This file is machine generated. All edits will be overwritten\n#\n')
|
||||||
|
output_subfrag (f, 'h')
|
||||||
|
output_subfrag (f, 'i')
|
||||||
|
output_subfrag (f, 'cc')
|
||||||
|
f.close ()
|
||||||
|
|
||||||
|
def output_ifile_include (dirname):
|
||||||
|
global do_sources
|
||||||
|
if do_sources:
|
||||||
|
f = open ('%s_generated.i' % (dirname,), 'w')
|
||||||
|
f.write ('//\n// This file is machine generated. All edits will be overwritten\n//\n')
|
||||||
|
files = name_dict.setdefault ('i', [])
|
||||||
|
files.sort ()
|
||||||
|
f.write ('%{\n')
|
||||||
|
for file in files:
|
||||||
|
f.write ('#include <%s>\n' % (file[0:-1] + 'h',))
|
||||||
|
f.write ('%}\n\n')
|
||||||
|
for file in files:
|
||||||
|
f.write ('%%include <%s>\n' % (file,))
|
||||||
|
|
||||||
|
def output_subfrag (f, ext):
|
||||||
|
files = name_dict.setdefault (ext, [])
|
||||||
|
files.sort ()
|
||||||
|
f.write ("GENERATED_%s =" % (ext.upper ()))
|
||||||
|
for file in files:
|
||||||
|
f.write (" \\\n\t%s" % (file,))
|
||||||
|
f.write ("\n\n")
|
||||||
|
|
||||||
|
def extract_extension (template_name):
|
||||||
|
# template name is something like: GrFIRfilterXXX.h.t
|
||||||
|
# we return everything between the penultimate . and .t
|
||||||
|
mo = re.search (r'\.([a-z]+)\.t$', template_name)
|
||||||
|
if not mo:
|
||||||
|
raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,)
|
||||||
|
return mo.group (1)
|
||||||
|
|
||||||
|
def open_src (name, mode):
|
||||||
|
global srcdir
|
||||||
|
return open (os.path.join (srcdir, name), mode)
|
||||||
|
|
||||||
|
def do_substitution (d, in_file, out_file):
|
||||||
|
def repl (match_obj):
|
||||||
|
key = match_obj.group (1)
|
||||||
|
# print key
|
||||||
|
return d[key]
|
||||||
|
|
||||||
|
inp = in_file.read ()
|
||||||
|
out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp)
|
||||||
|
out_file.write (out)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
copyright = '''/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2003,2004 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.
|
||||||
|
*/
|
||||||
|
'''
|
||||||
|
|
||||||
|
def is_complex (code3):
|
||||||
|
if i_code (code3) == 'c' or o_code (code3) == 'c':
|
||||||
|
return '1'
|
||||||
|
else:
|
||||||
|
return '0'
|
||||||
|
|
||||||
|
|
||||||
|
def standard_dict (name, code3, package='gr'):
|
||||||
|
d = {}
|
||||||
|
d['NAME'] = name
|
||||||
|
d['NAME_IMPL'] = name+'_impl'
|
||||||
|
d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
|
||||||
|
d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper())
|
||||||
|
d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
|
||||||
|
d['SPTR_NAME'] = '%s_sptr' % name
|
||||||
|
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
|
||||||
|
d['COPYRIGHT'] = copyright
|
||||||
|
d['TYPE'] = i_type (code3)
|
||||||
|
d['I_TYPE'] = i_type (code3)
|
||||||
|
d['O_TYPE'] = o_type (code3)
|
||||||
|
d['TAP_TYPE'] = tap_type (code3)
|
||||||
|
d['IS_COMPLEX'] = is_complex (code3)
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def standard_dict2 (name, code3, package):
|
||||||
|
d = {}
|
||||||
|
d['NAME'] = name
|
||||||
|
d['BASE_NAME'] = name
|
||||||
|
d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
|
||||||
|
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
|
||||||
|
d['COPYRIGHT'] = copyright
|
||||||
|
d['TYPE'] = i_type (code3)
|
||||||
|
d['I_TYPE'] = i_type (code3)
|
||||||
|
d['O_TYPE'] = o_type (code3)
|
||||||
|
d['TAP_TYPE'] = tap_type (code3)
|
||||||
|
d['IS_COMPLEX'] = is_complex (code3)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def standard_impl_dict2 (name, code3, package):
|
||||||
|
d = {}
|
||||||
|
d['NAME'] = name
|
||||||
|
d['IMPL_NAME'] = name
|
||||||
|
d['BASE_NAME'] = name.rstrip("impl").rstrip("_")
|
||||||
|
d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
|
||||||
|
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
|
||||||
|
d['COPYRIGHT'] = copyright
|
||||||
|
d['FIR_TYPE'] = "fir_filter_" + code3
|
||||||
|
d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
|
||||||
|
d['TYPE'] = i_type (code3)
|
||||||
|
d['I_TYPE'] = i_type (code3)
|
||||||
|
d['O_TYPE'] = o_type (code3)
|
||||||
|
d['TAP_TYPE'] = tap_type (code3)
|
||||||
|
d['IS_COMPLEX'] = is_complex (code3)
|
||||||
|
return d
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2004 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
def i_code (code3):
|
||||||
|
return code3[0]
|
||||||
|
|
||||||
|
def o_code (code3):
|
||||||
|
if len (code3) >= 2:
|
||||||
|
return code3[1]
|
||||||
|
else:
|
||||||
|
return code3[0]
|
||||||
|
|
||||||
|
def tap_code (code3):
|
||||||
|
if len (code3) >= 3:
|
||||||
|
return code3[2]
|
||||||
|
else:
|
||||||
|
return code3[0]
|
||||||
|
|
||||||
|
def i_type (code3):
|
||||||
|
return char_to_type[i_code (code3)]
|
||||||
|
|
||||||
|
def o_type (code3):
|
||||||
|
return char_to_type[o_code (code3)]
|
||||||
|
|
||||||
|
def tap_type (code3):
|
||||||
|
return char_to_type[tap_code (code3)]
|
||||||
|
|
||||||
|
|
||||||
|
char_to_type = {}
|
||||||
|
char_to_type['s'] = 'short'
|
||||||
|
char_to_type['i'] = 'int'
|
||||||
|
char_to_type['f'] = 'float'
|
||||||
|
char_to_type['c'] = 'gr_complex'
|
||||||
|
char_to_type['b'] = 'unsigned char'
|
||||||
+11
-1
@@ -26,6 +26,11 @@ endif()
|
|||||||
include(GrSwig)
|
include(GrSwig)
|
||||||
include(GrPython)
|
include(GrPython)
|
||||||
|
|
||||||
|
set(GR_SWIG_INCLUDE_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../include/
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/../include/
|
||||||
|
)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Setup swig generation
|
# Setup swig generation
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -35,7 +40,12 @@ endforeach(incdir)
|
|||||||
|
|
||||||
set(GR_SWIG_LIBRARIES gnuradio-ieee802_11)
|
set(GR_SWIG_LIBRARIES gnuradio-ieee802_11)
|
||||||
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/ieee802_11_swig_doc.i)
|
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/ieee802_11_swig_doc.i)
|
||||||
set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
set(GR_SWIG_DOC_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../include/ieee802-11/
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/../include/ieee802-11/
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GR_SWIG_TARGET_DEPS ieee802_11_generated_includes)
|
||||||
|
|
||||||
GR_SWIG_MAKE(ieee802_11_swig ieee802_11_swig.i)
|
GR_SWIG_MAKE(ieee802_11_swig ieee802_11_swig.i)
|
||||||
|
|
||||||
|
|||||||
@@ -22,27 +22,54 @@
|
|||||||
|
|
||||||
%{
|
%{
|
||||||
#include "ieee802-11/ether_encap.h"
|
#include "ieee802-11/ether_encap.h"
|
||||||
|
#include "ieee802-11/moving_average_cc.h"
|
||||||
|
#include "ieee802-11/moving_average_ff.h"
|
||||||
#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_mapper.h"
|
||||||
#include "ieee802-11/ofdm_parse_mac.h"
|
#include "ieee802-11/ofdm_parse_mac.h"
|
||||||
|
#include "ieee802-11/ofdm_pilot.h"
|
||||||
|
#include "ieee802-11/ofdm_preamble.h"
|
||||||
#include "ieee802-11/ofdm_sync_long.h"
|
#include "ieee802-11/ofdm_sync_long.h"
|
||||||
#include "ieee802-11/ofdm_sync_short.h"
|
#include "ieee802-11/ofdm_sync_short.h"
|
||||||
|
#include "ieee802-11/wave_llc.h"
|
||||||
|
#include "ieee802-11/wave_short_message.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "ieee802-11/ether_encap.h"
|
%include "ieee802-11/ether_encap.h"
|
||||||
|
%include "ieee802-11/moving_average_cc.h"
|
||||||
|
%include "ieee802-11/moving_average_ff.h"
|
||||||
%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_mapper.h"
|
||||||
%include "ieee802-11/ofdm_parse_mac.h"
|
%include "ieee802-11/ofdm_parse_mac.h"
|
||||||
|
%include "ieee802-11/ofdm_pilot.h"
|
||||||
|
%include "ieee802-11/ofdm_preamble.h"
|
||||||
%include "ieee802-11/ofdm_sync_long.h"
|
%include "ieee802-11/ofdm_sync_long.h"
|
||||||
%include "ieee802-11/ofdm_sync_short.h"
|
%include "ieee802-11/ofdm_sync_short.h"
|
||||||
|
%include "ieee802-11/wave_llc.h"
|
||||||
|
%include "ieee802-11/wave_short_message.h"
|
||||||
|
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ether_encap);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ether_encap);
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, moving_average_cc);
|
||||||
|
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_mapper);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_parse_mac);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_parse_mac);
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_pilot);
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_preamble);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_long);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_long);
|
||||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_short);
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_short);
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, wave_llc);
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(ieee802_11, wave_short_message);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user