rename
This commit is contained in:
@@ -1339,7 +1339,7 @@
|
||||
</param>
|
||||
<param>
|
||||
<key>log</key>
|
||||
<value>False</value>
|
||||
<value>True</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>maxoutbuf</key>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Decode MAC</name>
|
||||
<key>ieee802_11_ofdm_decode_mac</key>
|
||||
<name>WiFi Decode MAC</name>
|
||||
<key>ieee802_11_decode_mac</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_decode_mac($log, $debug)</make>
|
||||
<make>ieee802_11.decode_mac($log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Decode Signal</name>
|
||||
<key>ieee802_11_ofdm_decode_signal</key>
|
||||
<name>WiFi Decode Signal</name>
|
||||
<key>ieee802_11_decode_signal</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_decode_signal($log, $debug)</make>
|
||||
<make>ieee802_11.decode_signal($log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Equalize Symbols</name>
|
||||
<key>ieee802_11_ofdm_equalize_symbols</key>
|
||||
<name>WiFi Equalize Symbols</name>
|
||||
<key>ieee802_11_equalize_symbols</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_equalize_symbols($algo, $debug)</make>
|
||||
<make>ieee802_11.equalize_symbols($algo, $debug)</make>
|
||||
<callback>set_algorithm($algo)</callback>
|
||||
|
||||
<param>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM MAC</name>
|
||||
<key>ieee802_11_ofdm_mac</key>
|
||||
<name>WiFi MAC</name>
|
||||
<key>ieee802_11_mac</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_mac($src_mac, $dst_mac, $bss_mac)</make>
|
||||
<make>ieee802_11.mac($src_mac, $dst_mac, $bss_mac)</make>
|
||||
|
||||
<param>
|
||||
<name>SRC MAC</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Mapper</name>
|
||||
<key>ieee802_11_ofdm_mapper</key>
|
||||
<name>WiFi Mapper</name>
|
||||
<key>ieee802_11_mapper</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_mapper($encoding, $debug)</make>
|
||||
<make>ieee802_11.mapper($encoding, $debug)</make>
|
||||
<callback>set_encoding($encoding)</callback>
|
||||
|
||||
<param>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Parse MAC</name>
|
||||
<key>ieee802_11_ofdm_parse_mac</key>
|
||||
<name>WiFi Parse MAC</name>
|
||||
<key>ieee802_11_parse_mac</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_parse_mac($log, $debug)</make>
|
||||
<make>ieee802_11.parse_mac($log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Sync Long</name>
|
||||
<key>ieee802_11_ofdm_sync_long</key>
|
||||
<name>WiFi Sync Long</name>
|
||||
<key>ieee802_11_sync_long</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_sync_long($sync_length, $log, $debug)</make>
|
||||
<make>ieee802_11.sync_long($sync_length, $log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<block>
|
||||
<name>OFDM Sync Short</name>
|
||||
<key>ieee802_11_ofdm_sync_short</key>
|
||||
<name>WiFi Sync Short</name>
|
||||
<key>ieee802_11_sync_short</key>
|
||||
<category>IEEE802.11</category>
|
||||
<import>import ieee802_11</import>
|
||||
<make>ieee802_11.ofdm_sync_short($threshold, $min_plateau, $log, $debug)</make>
|
||||
<make>ieee802_11.sync_short($threshold, $min_plateau, $log, $debug)</make>
|
||||
|
||||
<param>
|
||||
<name>Log</name>
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
# Copyright (C) 2013, 2016 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
|
||||
@@ -70,16 +70,16 @@ list(APPEND include_sources
|
||||
${generated_includes}
|
||||
api.h
|
||||
chunks_to_symbols.h
|
||||
decode_mac.h
|
||||
decode_signal.h
|
||||
equalize_symbols.h
|
||||
ether_encap.h
|
||||
ofdm_decode_mac.h
|
||||
ofdm_decode_signal.h
|
||||
ofdm_equalize_symbols.h
|
||||
ofdm_mac.h
|
||||
ofdm_mapper.h
|
||||
ofdm_parse_mac.h
|
||||
ofdm_sync_long.h
|
||||
ofdm_sync_short.h
|
||||
wifi_signal_field.h
|
||||
mac.h
|
||||
mapper.h
|
||||
parse_mac.h
|
||||
signal_field.h
|
||||
sync_long.h
|
||||
sync_short.h
|
||||
)
|
||||
|
||||
install(
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
|
||||
class IEEE802_11_API chunks_to_symbols : virtual public tagged_stream_block
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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_PARSE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H
|
||||
#ifndef INCLUDED_IEEE802_11_DECODE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_DECODE_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_parse_mac : virtual public block
|
||||
class IEEE802_11_API decode_mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_parse_mac> sptr;
|
||||
typedef boost::shared_ptr<decode_mac> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
@@ -35,4 +35,6 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_PARSE_MAC_H */
|
||||
#endif /* INCLUDED_IEEE802_11_DECODE_MAC_H */
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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_DECODE_SIGNAL_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_DECODE_SIGNAL_H
|
||||
#ifndef INCLUDED_IEEE802_11_DECODE_SIGNAL_H
|
||||
#define INCLUDED_IEEE802_11_DECODE_SIGNAL_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_decode_signal : virtual public block
|
||||
class IEEE802_11_API decode_signal : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_decode_signal> sptr;
|
||||
typedef boost::shared_ptr<decode_signal> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
@@ -35,5 +35,5 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_DECODE_SIGNAL_H */
|
||||
#endif /* INCLUDED_IEEE802_11_DECODE_SIGNAL_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2015 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2015, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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_EQUALIZE_SYMBOLS_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H
|
||||
#ifndef INCLUDED_IEEE802_11_EQUALIZE_SYMBOLS_H
|
||||
#define INCLUDED_IEEE802_11_EQUALIZE_SYMBOLS_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -28,11 +28,11 @@ enum Equalizer {
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_equalize_symbols : virtual public block
|
||||
class IEEE802_11_API equalize_symbols : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_equalize_symbols> sptr;
|
||||
typedef boost::shared_ptr<equalize_symbols> sptr;
|
||||
static sptr make(Equalizer algo, bool debug = false);
|
||||
virtual void set_algorithm(Equalizer algo) = 0;
|
||||
|
||||
@@ -41,5 +41,5 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H*/
|
||||
#endif /* INCLUDED_IEEE802_11_EQUALIZE_SYMBOLS_H*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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
|
||||
#ifndef INCLUDED_IEEE802_11_MAC_H
|
||||
#define INCLUDED_IEEE802_11_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_mac : virtual public block
|
||||
class IEEE802_11_API mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_mac> sptr;
|
||||
typedef boost::shared_ptr<mac> sptr;
|
||||
static sptr make(std::vector<uint8_t> src_mac,
|
||||
std::vector<uint8_t> dst_mac,
|
||||
std::vector<uint8_t> bss_mac);
|
||||
@@ -36,4 +36,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_MAC_H */
|
||||
#endif /* INCLUDED_IEEE802_11_MAC_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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
|
||||
#ifndef INCLUDED_IEEE802_11_MAPPER_H
|
||||
#define INCLUDED_IEEE802_11_MAPPER_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -34,11 +34,11 @@ enum Encoding {
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_mapper : virtual public block
|
||||
class IEEE802_11_API mapper : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_mapper> sptr;
|
||||
|
||||
typedef boost::shared_ptr<mapper> sptr;
|
||||
static sptr make(Encoding mcs, bool debug = false);
|
||||
virtual void set_encoding(Encoding mcs) = 0;
|
||||
};
|
||||
@@ -46,4 +46,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_MAPPER_H */
|
||||
#endif /* INCLUDED_IEEE802_11_MAPPER_H */
|
||||
@@ -1,47 +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_DECODE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_decode_mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_decode_mac> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
private:
|
||||
|
||||
// Puncturing vectors
|
||||
static const unsigned char d_puncture_1_2[];
|
||||
static const unsigned char d_puncture_2_3[];
|
||||
static const unsigned char d_puncture_3_4[];
|
||||
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_DECODE_MAC_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 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_PARSE_MAC_H
|
||||
#define INCLUDED_IEEE802_11_PARSE_MAC_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API parse_mac : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<parse_mac> sptr;
|
||||
static sptr make(bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_PARSE_MAC_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -15,8 +15,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H
|
||||
#define INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H
|
||||
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_H
|
||||
#define INCLUDED_IEEE802_11_SIGNAL_FIELD_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/digital/packet_header_default.h>
|
||||
@@ -24,18 +24,18 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API wifi_signal_field : virtual public digital::packet_header_default
|
||||
class IEEE802_11_API signal_field : virtual public digital::packet_header_default
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<wifi_signal_field> sptr;
|
||||
typedef boost::shared_ptr<signal_field> sptr;
|
||||
static sptr make();
|
||||
|
||||
protected:
|
||||
wifi_signal_field();
|
||||
signal_field();
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_H */
|
||||
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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_SYNC_LONG_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H
|
||||
#ifndef INCLUDED_IEEE802_11_SYNC_LONG_H
|
||||
#define INCLUDED_IEEE802_11_SYNC_LONG_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_sync_long : virtual public block
|
||||
class IEEE802_11_API sync_long : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_sync_long> sptr;
|
||||
typedef boost::shared_ptr<sync_long> sptr;
|
||||
static sptr make(unsigned int sync_length,
|
||||
bool log = false, bool debug = false);
|
||||
|
||||
@@ -36,4 +36,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_SYNC_LONG_H */
|
||||
#endif /* INCLUDED_IEEE802_11_SYNC_LONG_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,8 +14,8 @@
|
||||
* 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_SYNC_SHORT_H
|
||||
#define INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H
|
||||
#ifndef INCLUDED_IEEE802_11_SYNC_SHORT_H
|
||||
#define INCLUDED_IEEE802_11_SYNC_SHORT_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
@@ -23,11 +23,11 @@
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class IEEE802_11_API ofdm_sync_short : virtual public block
|
||||
class IEEE802_11_API sync_short : virtual public block
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<ofdm_sync_short> sptr;
|
||||
typedef boost::shared_ptr<sync_short> sptr;
|
||||
static sptr make(double threshold, unsigned int min_plateau, bool log = false, bool debug = false);
|
||||
|
||||
};
|
||||
@@ -35,4 +35,4 @@ public:
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_SYNC_SHORT_H */
|
||||
#endif /* INCLUDED_IEEE802_11_SYNC_SHORT_H */
|
||||
+12
-11
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
# Copyright (C) 2013, 2016 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
|
||||
@@ -94,20 +94,21 @@ add_dependencies(ieee802_11_generated_sources ieee802_11_generated_includes)
|
||||
########################################################################
|
||||
list(APPEND gr_ieee802_11_sources
|
||||
${generated_sources}
|
||||
chunks_to_symbols_impl.cc
|
||||
constellations.cc
|
||||
decode_mac.cc
|
||||
decode_signal.cc
|
||||
equalize_symbols.cc
|
||||
equalizer/linear_comb.cc
|
||||
equalizer/lms.cc
|
||||
chunks_to_symbols_impl.cc
|
||||
ether_encap_impl.cc
|
||||
ofdm_decode_mac.cc
|
||||
ofdm_decode_signal.cc
|
||||
ofdm_equalize_symbols.cc
|
||||
ofdm_mac.cc
|
||||
ofdm_mapper.cc
|
||||
ofdm_parse_mac.cc
|
||||
ofdm_sync_long.cc
|
||||
ofdm_sync_short.cc
|
||||
mac.cc
|
||||
mapper.cc
|
||||
parse_mac.cc
|
||||
signal_field_impl.cc
|
||||
sync_long.cc
|
||||
sync_short.cc
|
||||
utils.cc
|
||||
wifi_signal_field_impl.cc
|
||||
)
|
||||
|
||||
list(APPEND gr_ieee802_11_libs
|
||||
|
||||
@@ -29,7 +29,7 @@ chunks_to_symbols::make()
|
||||
}
|
||||
|
||||
chunks_to_symbols_impl::chunks_to_symbols_impl()
|
||||
: tagged_stream_block("wifi_chunks_to_symbols",
|
||||
: tagged_stream_block("chunks_to_symbols",
|
||||
io_signature::make(1, 1, sizeof(char)),
|
||||
io_signature::make(1, 1, sizeof(gr_complex)), "packet_len") {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2016 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/decode_mac.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <itpp/itcomm.h>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
using namespace itpp;
|
||||
|
||||
class decode_mac_impl : public decode_mac {
|
||||
|
||||
public:
|
||||
decode_mac_impl(bool log, bool debug) : block("decode_mac",
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_log(log),
|
||||
d_debug(debug),
|
||||
d_ofdm(BPSK_1_2),
|
||||
d_frame(d_ofdm, 0),
|
||||
d_frame_complete(true) {
|
||||
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
|
||||
// bpsk
|
||||
int bpsk_bits[] = {0, 1};
|
||||
bpsk.set(cvec(BPSK_D, 2), ivec(bpsk_bits, 2));
|
||||
|
||||
// qpsk
|
||||
int qpsk_bits[] = {0, 1, 2, 3};
|
||||
qpsk.set(cvec(QPSK_D, 4), ivec(qpsk_bits, 4));
|
||||
|
||||
// qam16
|
||||
int qam16_bits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
qam16.set(cvec(QAM16_D, 16), ivec(qam16_bits, 16));
|
||||
|
||||
// qam64
|
||||
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_D, 64), ivec(qam64_bits, 64));
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, 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];
|
||||
|
||||
int i = 0;
|
||||
|
||||
std::vector<gr::tag_t> tags;
|
||||
const uint64_t nread = this->nitems_read(0);
|
||||
|
||||
dout << "Decode MAC: input " << ninput_items[0] << std::endl;
|
||||
|
||||
while(i < ninput_items[0]) {
|
||||
|
||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
||||
pmt::string_to_symbol("wifi_start"));
|
||||
|
||||
if(tags.size()) {
|
||||
if (d_frame_complete == false) {
|
||||
dout << "Warning: starting to receive new frame before old frame was complete" << std::endl;
|
||||
dout << "Already copied " << copied << " out of " << d_frame.n_sym << " symbols of last frame" << std::endl;
|
||||
}
|
||||
d_frame_complete = false;
|
||||
|
||||
pmt::pmt_t tuple = tags[0].value;
|
||||
int len_data = pmt::to_uint64(pmt::car(tuple));
|
||||
int encoding = pmt::to_uint64(pmt::cdr(tuple));
|
||||
|
||||
ofdm_param ofdm = ofdm_param((Encoding)encoding);
|
||||
frame_param frame = frame_param(ofdm, len_data);
|
||||
|
||||
// sanity check, more than MAX_SYM may indicate garbage
|
||||
if(frame.n_sym <= MAX_SYM && frame.n_encoded_bits <= MAX_BITS) {
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
copied = 0;
|
||||
dout << "Decode MAC: frame start -- len " << len_data
|
||||
<< " symbols " << frame.n_sym << " encoding "
|
||||
<< encoding << std::endl;
|
||||
} else {
|
||||
dout << "Dropping frame which is too large (symbols or bits)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(copied < d_frame.n_sym) {
|
||||
dout << "copy one symbol, copied " << copied << " out of " << d_frame.n_sym << std::endl;
|
||||
std::memcpy(sym + (copied * 48), in, 48 * sizeof(gr_complex));
|
||||
copied++;
|
||||
|
||||
if(copied == d_frame.n_sym) {
|
||||
dout << "received complete frame - decoding" << std::endl;
|
||||
decode();
|
||||
in += 48;
|
||||
i++;
|
||||
d_frame_complete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in += 48;
|
||||
i++;
|
||||
}
|
||||
|
||||
consume(0, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void decode() {
|
||||
demodulate();
|
||||
deinterleave();
|
||||
decode_conv();
|
||||
descramble();
|
||||
print_output();
|
||||
|
||||
// skip service field
|
||||
boost::crc_32_type result;
|
||||
result.process_bytes(out_bytes + 2, d_frame.psdu_size);
|
||||
if(result.checksum() != 558161692) {
|
||||
dout << "checksum wrong -- dropping" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||
% d_ofdm.encoding % d_frame.psdu_size % d_frame.n_sym);
|
||||
|
||||
// create PDU
|
||||
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_frame.psdu_size - 4);
|
||||
pmt::pmt_t enc = pmt::from_uint64(d_ofdm.encoding);
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("encoding"), enc);
|
||||
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
|
||||
}
|
||||
|
||||
void demodulate() {
|
||||
|
||||
cvec symbols;
|
||||
symbols.set_length(d_frame.n_sym * 48);
|
||||
for(int i = 0; i < d_frame.n_sym * 48; i++) {
|
||||
symbols[i] = std::complex<double>(sym[i]);
|
||||
}
|
||||
|
||||
switch(d_ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case BPSK_3_4:
|
||||
|
||||
bits = to_vec(bpsk.demodulate_bits(symbols));
|
||||
break;
|
||||
|
||||
case QPSK_1_2:
|
||||
case QPSK_3_4:
|
||||
|
||||
bits = to_vec(qpsk.demodulate_bits(symbols));
|
||||
break;
|
||||
|
||||
case QAM16_1_2:
|
||||
case QAM16_3_4:
|
||||
bits = to_vec(qam16.demodulate_bits(symbols));
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
case QAM64_3_4:
|
||||
bits = to_vec(qam64.demodulate_bits(symbols));
|
||||
break;
|
||||
}
|
||||
|
||||
// I hate the guy who wrote itpp
|
||||
bits = bits * (-2) + 1;
|
||||
}
|
||||
|
||||
void deinterleave() {
|
||||
|
||||
int n_cbps = d_ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
int second[n_cbps];
|
||||
int s = std::max(d_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 < d_frame.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
deinter[i * n_cbps + second[first[k]]] = bits[i * n_cbps + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decode_conv() {
|
||||
Punctured_Convolutional_Code code;
|
||||
ivec generator(2);
|
||||
generator(0)=0133;
|
||||
generator(1)=0171;
|
||||
code.set_generator_polynomials(generator, 7);
|
||||
|
||||
bmat puncture_matrix;
|
||||
switch(d_ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
puncture_matrix = "1 1; 1 1";
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
puncture_matrix = "1 1 0; 1 0 1;";
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
puncture_matrix = "1 1 1 1 1 1; 1 0 1 0 1 0;";
|
||||
break;
|
||||
}
|
||||
code.set_puncture_matrix(puncture_matrix);
|
||||
code.set_truncation_length(30);
|
||||
|
||||
dout << "coding rate " << code.get_rate() << std::endl;
|
||||
dout << d_frame.n_encoded_bits << std::endl;
|
||||
|
||||
vec rx_signal(deinter, d_frame.n_encoded_bits);
|
||||
|
||||
code.reset();
|
||||
decoded_bits.set_length(d_frame.n_encoded_bits);
|
||||
code.decode_tail(rx_signal, decoded_bits);
|
||||
|
||||
//dout << "length decoded " << decoded_bits.size() << std::endl;
|
||||
//std::cout << decoded_bits << std::endl;
|
||||
}
|
||||
|
||||
void descramble () {
|
||||
int state = 0;
|
||||
for(int i = 0; i < 7; i++) {
|
||||
if(decoded_bits(i)) {
|
||||
state |= 1 << (6 - i);
|
||||
}
|
||||
}
|
||||
|
||||
int feedback;
|
||||
|
||||
for(int i = 7; i < decoded_bits.size(); i++) {
|
||||
feedback = ((!!(state & 64))) ^ (!!(state & 8));
|
||||
out_bits[i] = feedback ^ (int)decoded_bits(i);
|
||||
state = ((state << 1) & 0x7e) | feedback;
|
||||
}
|
||||
|
||||
for(int i = 0; i < decoded_bits.size(); i++) {
|
||||
int bit = i % 8;
|
||||
int byte = i / 8;
|
||||
if(bit == 0) {
|
||||
out_bytes[byte] = 0;
|
||||
}
|
||||
|
||||
if(out_bits[i]) {
|
||||
out_bytes[byte] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_output() {
|
||||
|
||||
dout << std::endl;
|
||||
for(int i = 0; i < decoded_bits.size() / 8; i++) {
|
||||
dout << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " ";
|
||||
if(i % 16 == 15) {
|
||||
dout << std::endl;
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
for(int i = 0; i < decoded_bits.size() / 8; i++) {
|
||||
if((out_bytes[i] > 31) && (out_bytes[i] < 127)) {
|
||||
dout << ((char) out_bytes[i]);
|
||||
} else {
|
||||
dout << ".";
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
gr_complex sym[1000 * 48 * 100];
|
||||
vec bits;
|
||||
double deinter[1000 * 48];
|
||||
char out_bits[40000];
|
||||
char out_bytes[40000];
|
||||
bvec decoded_bits;
|
||||
|
||||
bool d_debug;
|
||||
bool d_log;
|
||||
frame_param d_frame;
|
||||
ofdm_param d_ofdm;
|
||||
int copied;
|
||||
bool d_frame_complete;
|
||||
|
||||
Modulator<std::complex<double> > bpsk;
|
||||
Modulator<std::complex<double> > qpsk;
|
||||
Modulator<std::complex<double> > qam16;
|
||||
Modulator<std::complex<double> > qam64;
|
||||
};
|
||||
|
||||
decode_mac::sptr
|
||||
decode_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new decode_mac_impl(log, debug));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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_decode_signal.h>
|
||||
#include <ieee802-11/decode_signal.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include "utils.h"
|
||||
|
||||
@@ -24,10 +24,10 @@ using namespace gr::ieee802_11;
|
||||
using namespace itpp;
|
||||
|
||||
|
||||
class ofdm_decode_signal_impl : public ofdm_decode_signal {
|
||||
class decode_signal_impl : public decode_signal {
|
||||
|
||||
public:
|
||||
ofdm_decode_signal_impl(bool log, bool debug) : block("ofdm_decode_signal",
|
||||
decode_signal_impl(bool log, bool debug) : block("decode_signal",
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
||||
d_log(log),
|
||||
@@ -39,7 +39,7 @@ ofdm_decode_signal_impl(bool log, bool debug) : block("ofdm_decode_signal",
|
||||
set_tag_propagation_policy(block::TPP_DONT);
|
||||
}
|
||||
|
||||
~ofdm_decode_signal_impl(){
|
||||
~decode_signal_impl(){
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
@@ -61,7 +61,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
while((i < ninput_items[0]) && (o < noutput_items)) {
|
||||
|
||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
||||
pmt::string_to_symbol("ofdm_start"));
|
||||
pmt::string_to_symbol("wifi_start"));
|
||||
|
||||
if(tags.size()) {
|
||||
for(int n = 0; n < 48; n++) {
|
||||
@@ -75,7 +75,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
if(print_signal()) {
|
||||
|
||||
add_item_tag(0, nitems_written(0) + o,
|
||||
pmt::string_to_symbol("ofdm_start"),
|
||||
pmt::string_to_symbol("wifi_start"),
|
||||
pmt::cons(pmt::from_uint64(d_len),
|
||||
pmt::from_uint64(d_encoding)),
|
||||
pmt::string_to_symbol(name()));
|
||||
@@ -213,10 +213,10 @@ private:
|
||||
static int inter[48];
|
||||
};
|
||||
|
||||
ofdm_decode_signal::sptr
|
||||
ofdm_decode_signal::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_decode_signal_impl(log, debug));
|
||||
decode_signal::sptr
|
||||
decode_signal::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new 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 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};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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_equalize_symbols.h>
|
||||
#include <ieee802-11/equalize_symbols.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "equalizer/base.h"
|
||||
@@ -25,10 +25,10 @@
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
|
||||
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
|
||||
class equalize_symbols_impl : public equalize_symbols {
|
||||
|
||||
public:
|
||||
ofdm_equalize_symbols_impl(Equalizer algo, bool debug) : block("ofdm_equalize_symbols",
|
||||
equalize_symbols_impl(Equalizer algo, bool debug) : block("equalize_symbols",
|
||||
gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, 48 * sizeof(gr_complex))),
|
||||
d_debug(debug), d_equalizer(NULL) {
|
||||
@@ -38,7 +38,7 @@ ofdm_equalize_symbols_impl(Equalizer algo, bool debug) : block("ofdm_equalize_sy
|
||||
set_algorithm(algo);
|
||||
}
|
||||
|
||||
~ofdm_equalize_symbols_impl(){
|
||||
~equalize_symbols_impl(){
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
@@ -57,7 +57,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
|
||||
while((i < ninput_items[0]) && (o < noutput_items)) {
|
||||
|
||||
get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("ofdm_start"));
|
||||
get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("wifi_start"));
|
||||
|
||||
// new WiFi frame
|
||||
if(tags.size()) {
|
||||
@@ -67,7 +67,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
// first data symbol (= signal field)
|
||||
if(d_nsym == 2) {
|
||||
add_item_tag(0, nitems_written(0) + o,
|
||||
pmt::string_to_symbol("ofdm_start"),
|
||||
pmt::string_to_symbol("wifi_start"),
|
||||
pmt::PMT_T,
|
||||
pmt::string_to_symbol(name()));
|
||||
}
|
||||
@@ -113,8 +113,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
ofdm_equalize_symbols::sptr
|
||||
ofdm_equalize_symbols::make(Equalizer algo, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_equalize_symbols_impl(algo, debug));
|
||||
equalize_symbols::sptr
|
||||
equalize_symbols::make(Equalizer algo, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new equalize_symbols_impl(algo, debug));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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 <ieee802-11/mac.h>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/block_detail.h>
|
||||
@@ -34,12 +34,12 @@
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
class ofdm_mac_impl : public ofdm_mac {
|
||||
class mac_impl : public mac {
|
||||
|
||||
public:
|
||||
|
||||
ofdm_mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) :
|
||||
block("ofdm_mac",
|
||||
mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) :
|
||||
block("mac",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_seq_nr(0) {
|
||||
@@ -48,10 +48,10 @@ ofdm_mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::v
|
||||
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));
|
||||
set_msg_handler(pmt::mp("app in"), boost::bind(&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));
|
||||
set_msg_handler(pmt::mp("phy in"), boost::bind(&mac_impl::phy_in, this, _1));
|
||||
|
||||
if(!check_mac(src_mac)) throw std::invalid_argument("wrong mac address size");
|
||||
if(!check_mac(dst_mac)) throw std::invalid_argument("wrong mac address size");
|
||||
@@ -73,7 +73,7 @@ void phy_in (pmt::pmt_t msg) {
|
||||
// TODO: check for frame type to determine header size
|
||||
pmt::pmt_t blob(pmt::cdr(msg));
|
||||
const char *mpdu = reinterpret_cast<const char *>(pmt::blob_data(blob));
|
||||
//std::cout << "pdu len " << pmt::blob_length(blob) << std::endl;
|
||||
std::cout << "pdu len " << pmt::blob_length(blob) << std::endl;
|
||||
pmt::pmt_t msdu = pmt::make_blob(mpdu + 24, pmt::blob_length(blob) - 24);
|
||||
|
||||
message_port_pub(pmt::mp("app out"), pmt::cons(pmt::car(msg), msdu));
|
||||
@@ -102,7 +102,7 @@ void app_in (pmt::pmt_t msg) {
|
||||
msdu = reinterpret_cast<const char *>(pmt::blob_data(pmt::cdr(msg)));
|
||||
|
||||
} else {
|
||||
throw std::invalid_argument("OFDM MAC expects PDUs or strings");
|
||||
throw std::invalid_argument("MAC expects PDUs or strings");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,8 +175,8 @@ private:
|
||||
uint8_t d_psdu[1528];
|
||||
};
|
||||
|
||||
ofdm_mac::sptr
|
||||
ofdm_mac::make(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_mac_impl(src_mac, dst_mac, bss_mac));
|
||||
mac::sptr
|
||||
mac::make(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) {
|
||||
return gnuradio::get_initial_sptr(new mac_impl(src_mac, dst_mac, bss_mac));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,20 +14,20 @@
|
||||
* 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 <ieee802-11/mapper.h>
|
||||
#include "utils.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
|
||||
class ofdm_mapper_impl : public ofdm_mapper {
|
||||
class mapper_impl : public mapper {
|
||||
public:
|
||||
|
||||
static const int DATA_CARRIERS = 48;
|
||||
|
||||
ofdm_mapper_impl(Encoding e, bool debug) :
|
||||
block ("ofdm_mapper",
|
||||
mapper_impl(Encoding e, bool debug) :
|
||||
block ("mapper",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(1, 1, sizeof(char))),
|
||||
d_symbols_offset(0),
|
||||
@@ -39,14 +39,14 @@ ofdm_mapper_impl(Encoding e, bool debug) :
|
||||
set_encoding(e);
|
||||
}
|
||||
|
||||
~ofdm_mapper_impl() {
|
||||
~mapper_impl() {
|
||||
free(d_symbols);
|
||||
}
|
||||
|
||||
void print_message(const char *msg, size_t len) {
|
||||
|
||||
|
||||
dout << std::hex << "OFDM MAPPER input symbols" << std::endl
|
||||
dout << std::hex << "MAPPER input symbols" << std::endl
|
||||
<< "===========================" << std::endl;
|
||||
|
||||
for(int i = 0; i < len; i++) {
|
||||
@@ -62,7 +62,7 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
||||
gr_vector_void_star& output_items ) {
|
||||
|
||||
unsigned char *out = (unsigned char*)output_items[0];
|
||||
dout << "OFDM MAPPER called offset: " << d_symbols_offset <<
|
||||
dout << "MAPPER called offset: " << d_symbols_offset <<
|
||||
" length: " << d_symbols_len << std::endl;
|
||||
|
||||
while(!d_symbols_offset) {
|
||||
@@ -74,56 +74,56 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
||||
}
|
||||
|
||||
if(pmt::is_pair(msg)) {
|
||||
dout << "OFDM MAPPER: received new message" << std::endl;
|
||||
dout << "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);
|
||||
if(tx.n_sym > MAX_SYM) {
|
||||
frame_param frame(d_ofdm, psdu_length);
|
||||
if(frame.n_sym > MAX_SYM) {
|
||||
std::cout << "packet too large, maximum number of symbols is " << MAX_SYM << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//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), sizeof(char));
|
||||
char *data_bits = (char*)calloc(frame.n_data, sizeof(char));
|
||||
char *scrambled_data = (char*)calloc(frame.n_data, sizeof(char));
|
||||
char *encoded_data = (char*)calloc(frame.n_data * 2, sizeof(char));
|
||||
char *punctured_data = (char*)calloc(frame.n_encoded_bits, sizeof(char));
|
||||
char *interleaved_data = (char*)calloc(frame.n_encoded_bits, sizeof(char));
|
||||
char *symbols = (char*)calloc((frame.n_encoded_bits / d_ofdm.n_bpsc), 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);
|
||||
//generate the WIFI data field, adding service field and pad bits
|
||||
generate_bits(psdu, data_bits, frame);
|
||||
//print_hex_array(data_bits, frame.n_data);
|
||||
|
||||
// scrambling
|
||||
static uint8_t scrambler = 1;
|
||||
scramble(data_bits, scrambled_data, tx, scrambler++);
|
||||
scramble(data_bits, scrambled_data, frame, scrambler++);
|
||||
if(scrambler > 127) {
|
||||
scrambler = 1;
|
||||
}
|
||||
|
||||
//print_hex_array(scrambled_data, tx.n_data);
|
||||
//print_hex_array(scrambled_data, frame.n_data);
|
||||
// reset tail bits
|
||||
reset_tail_bits(scrambled_data, tx);
|
||||
//print_hex_array(scrambled_data, tx.n_data);
|
||||
reset_tail_bits(scrambled_data, frame);
|
||||
//print_hex_array(scrambled_data, frame.n_data);
|
||||
// encoding
|
||||
convolutional_encoding(scrambled_data, encoded_data, tx);
|
||||
//print_hex_array(encoded_data, tx.n_data * 2);
|
||||
convolutional_encoding(scrambled_data, encoded_data, frame);
|
||||
//print_hex_array(encoded_data, frame.n_data * 2);
|
||||
// puncturing
|
||||
puncturing(encoded_data, punctured_data, tx, d_ofdm);
|
||||
puncturing(encoded_data, punctured_data, frame, d_ofdm);
|
||||
//std::cout << "punctured" << std::endl;
|
||||
// interleaving
|
||||
interleave(punctured_data, interleaved_data, tx, d_ofdm);
|
||||
interleave(punctured_data, interleaved_data, frame, d_ofdm);
|
||||
//std::cout << "interleaved" << std::endl;
|
||||
|
||||
// one byte per symbol
|
||||
split_symbols(interleaved_data, symbols, tx, d_ofdm);
|
||||
split_symbols(interleaved_data, symbols, frame, d_ofdm);
|
||||
|
||||
d_symbols_len = tx.n_sym * 48;
|
||||
d_symbols_len = frame.n_sym * 48;
|
||||
|
||||
d_symbols = (char*)calloc(d_symbols_len, 1);
|
||||
std::memcpy(d_symbols, symbols, d_symbols_len);
|
||||
@@ -170,7 +170,7 @@ int general_work(int noutput, gr_vector_int& ninput_items,
|
||||
|
||||
void set_encoding(Encoding encoding) {
|
||||
|
||||
std::cout << "OFDM MAPPER: encoding: " << encoding << std::endl;
|
||||
std::cout << "MAPPER: encoding: " << encoding << std::endl;
|
||||
gr::thread::scoped_lock lock(d_mutex);
|
||||
|
||||
d_ofdm = ofdm_param(encoding);
|
||||
@@ -185,7 +185,7 @@ private:
|
||||
gr::thread::mutex d_mutex;
|
||||
};
|
||||
|
||||
ofdm_mapper::sptr
|
||||
ofdm_mapper::make(Encoding mcs, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_mapper_impl(mcs, debug));
|
||||
mapper::sptr
|
||||
mapper::make(Encoding mcs, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new mapper_impl(mcs, debug));
|
||||
}
|
||||
@@ -1,500 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ieee802-11/ofdm_decode_mac.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <itpp/itcomm.h>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
static __m128i metric0[4] __attribute__ ((aligned(16)));
|
||||
static __m128i metric1[4] __attribute__ ((aligned(16)));
|
||||
static __m128i path0[4] __attribute__ ((aligned(16)));
|
||||
static __m128i path1[4] __attribute__ ((aligned(16)));
|
||||
struct viterbi_state state0[64];
|
||||
struct viterbi_state state1[64];
|
||||
static int d_init = 0;
|
||||
|
||||
int decoded_count;
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
using namespace itpp;
|
||||
|
||||
class ofdm_decode_mac_impl : public ofdm_decode_mac {
|
||||
|
||||
public:
|
||||
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(0, 0, 0)),
|
||||
d_log(log),
|
||||
d_debug(debug),
|
||||
d_ofdm(BPSK_1_2),
|
||||
d_tx(d_ofdm, 0),
|
||||
d_frame_complete(true) {
|
||||
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
|
||||
}
|
||||
|
||||
int general_work (int noutput_items, 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];
|
||||
|
||||
int i = 0;
|
||||
|
||||
std::vector<gr::tag_t> tags;
|
||||
const uint64_t nread = this->nitems_read(0);
|
||||
|
||||
dout << "Decode MAC: input " << ninput_items[0] << std::endl;
|
||||
|
||||
while(i < ninput_items[0]) {
|
||||
|
||||
get_tags_in_range(tags, 0, nread + i, nread + i + 1,
|
||||
pmt::string_to_symbol("ofdm_start"));
|
||||
|
||||
if(tags.size()) {
|
||||
if (d_frame_complete == false) {
|
||||
dout << "Warning: starting to receive new frame before old frame was complete" << std::endl;
|
||||
dout << "Already copied " << copied << " out of " << d_tx.n_sym << " symbols of last frame" << std::endl;
|
||||
}
|
||||
d_frame_complete = false;
|
||||
|
||||
pmt::pmt_t tuple = tags[0].value;
|
||||
int len_data = pmt::to_uint64(pmt::car(tuple));
|
||||
int encoding = pmt::to_uint64(pmt::cdr(tuple));
|
||||
|
||||
ofdm_param ofdm = ofdm_param((Encoding)encoding);
|
||||
tx_param tx = tx_param(ofdm, len_data);
|
||||
|
||||
// sanity check, more than MAX_SYM may indicate garbage
|
||||
if(tx.n_sym <= MAX_SYM && tx.n_encoded_bits <= MAX_BITS) {
|
||||
d_ofdm = ofdm;
|
||||
d_tx = tx;
|
||||
copied = 0;
|
||||
dout << "Decode MAC: frame start -- len " << len_data
|
||||
<< " symbols " << tx.n_sym << " encoding "
|
||||
<< encoding << std::endl;
|
||||
} else {
|
||||
dout << "Dropping frame which is too large (symbols or bits)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(copied < d_tx.n_sym) {
|
||||
dout << "copy one symbol, copied " << copied << " out of " << d_tx.n_sym << std::endl;
|
||||
std::memcpy(sym + (copied * 48), in, 48 * sizeof(gr_complex));
|
||||
copied++;
|
||||
|
||||
if(copied == d_tx.n_sym) {
|
||||
dout << "received complete frame - decoding" << std::endl;
|
||||
decode();
|
||||
in += 48;
|
||||
i++;
|
||||
d_frame_complete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in += 48;
|
||||
i++;
|
||||
}
|
||||
|
||||
consume(0, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void decode() {
|
||||
demodulate();
|
||||
deinterleave();
|
||||
decode_conv();
|
||||
descramble();
|
||||
print_output();
|
||||
|
||||
// skip service field
|
||||
boost::crc_32_type result;
|
||||
result.process_bytes(out_bytes + 2, d_tx.psdu_size);
|
||||
if(result.checksum() != 558161692) {
|
||||
dout << "checksum wrong -- dropping" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%")
|
||||
% d_ofdm.encoding % d_tx.psdu_size % d_tx.n_sym);
|
||||
|
||||
// create PDU
|
||||
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_tx.psdu_size - 4);
|
||||
pmt::pmt_t enc = pmt::from_uint64(d_ofdm.encoding);
|
||||
pmt::pmt_t dict = pmt::make_dict();
|
||||
dict = pmt::dict_add(dict, pmt::mp("encoding"), enc);
|
||||
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
|
||||
}
|
||||
|
||||
/***** Auxiliary functions used for demodulation *****/
|
||||
// BPSK
|
||||
bvec demodulate_bpsk(const cvec &signal) const
|
||||
{
|
||||
|
||||
bvec out(signal.size());
|
||||
out.set_size(signal.size(), false);
|
||||
|
||||
for (int i = 0; i < signal.length(); i++) {
|
||||
out(i) = bin(signal(i).real() > 0);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// QPSK
|
||||
bvec demodulate_qpsk(const cvec &signal) const
|
||||
{
|
||||
|
||||
int k = 2;
|
||||
|
||||
bvec out(k * signal.size());
|
||||
out.set_size(k * signal.size(), false);
|
||||
|
||||
for (int i = 0; i < signal.size(); i++) {
|
||||
out(k*i) = bin(signal(i).real() > 0);
|
||||
out(k*i + 1) = bin(signal(i).imag() > 0);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// 16QAM
|
||||
bvec demodulate_16qam(const cvec &signal) const
|
||||
{
|
||||
|
||||
int k = 4;
|
||||
|
||||
bvec out(k * signal.size());
|
||||
out.set_size(k * signal.size(), false);
|
||||
|
||||
for (int i = 0; i < signal.size(); i++) {
|
||||
out(k*i) = bin(signal(i).real() > 0);
|
||||
out(k*i + 1) = bin(std::abs(signal(i).real()) < 0.63245);
|
||||
out(k*i + 2) = bin(signal(i).imag() > 0);
|
||||
out(k*i + 3) = bin(std::abs(signal(i).imag()) < 0.63245);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// 64QAM
|
||||
bvec demodulate_64qam(const cvec &signal) const
|
||||
{
|
||||
|
||||
int k = 6;
|
||||
|
||||
bvec out(k * signal.size());
|
||||
out.set_size(k * signal.size(), false);
|
||||
|
||||
for (int i = 0; i < signal.size(); i++) {
|
||||
out(k*i) = bin(signal(i).real() > 0);
|
||||
out(k*i + 1) = bin(std::abs(signal(i).real()) < 0.6172);
|
||||
out(k*i + 2) = bin(std::abs(signal(i).real()) < 0.9258 && std::abs(signal(i).real()) > 0.3086);
|
||||
out(k*i + 3) = bin(signal(i).imag() > 0);
|
||||
out(k*i + 4) = bin(std::abs(signal(i).imag()) < 0.6172);
|
||||
out(k*i + 5) = bin(std::abs(signal(i).imag()) < 0.9258 && std::abs(signal(i).imag()) > 0.3086);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void demodulate() {
|
||||
|
||||
cvec symbols;
|
||||
symbols.set_length(d_tx.n_sym * 48);
|
||||
for(int i = 0; i < d_tx.n_sym * 48; i++) {
|
||||
symbols[i] = std::complex<double>(sym[i]);
|
||||
}
|
||||
|
||||
switch(d_ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case BPSK_3_4:
|
||||
bits = to_vec(demodulate_bpsk(symbols));
|
||||
break;
|
||||
|
||||
case QPSK_1_2:
|
||||
case QPSK_3_4:
|
||||
bits = to_vec(demodulate_qpsk(symbols));
|
||||
break;
|
||||
|
||||
case QAM16_1_2:
|
||||
case QAM16_3_4:
|
||||
bits = to_vec(demodulate_16qam(symbols));
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
case QAM64_3_4:
|
||||
bits = to_vec(demodulate_64qam(symbols));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void deinterleave() {
|
||||
|
||||
int n_cbps = d_ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
int second[n_cbps];
|
||||
int s = std::max(d_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));
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for(int i = 0; i < d_tx.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
if (bits[i * n_cbps + k] > 0)
|
||||
{
|
||||
d_tmp_inbits[i * n_cbps + second[first[k]]] = 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_tmp_inbits[i * n_cbps + second[first[k]]] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the appropiate coding rate for
|
||||
// the convolutional decoder.
|
||||
set_coding_rate();
|
||||
|
||||
if (d_ntraceback == 5)
|
||||
{
|
||||
count = d_tx.n_sym * n_cbps;
|
||||
d_inbits = d_tmp_inbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_inbits = d_inbits_punctured;
|
||||
count = 0;
|
||||
for(int i = 0; i < d_tx.n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
while (d_puncture[count % (2 * d_k)] == 0)
|
||||
{
|
||||
d_inbits[count] = 2;
|
||||
count++;
|
||||
}
|
||||
|
||||
// Insert received bits
|
||||
d_inbits[count] = d_tmp_inbits[i * n_cbps + k];
|
||||
count++;
|
||||
|
||||
while (d_puncture[count % (2 * d_k)] == 0)
|
||||
{
|
||||
d_inbits[count] = 2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = count; i < NeededBits(); i++)
|
||||
d_inbits[i] = 0x00;
|
||||
}
|
||||
|
||||
int NeededBits()
|
||||
{
|
||||
int return_value;
|
||||
if (d_ntraceback == 5)
|
||||
return_value = d_tx.n_encoded_bits / 2;
|
||||
else if (d_ntraceback == 9)
|
||||
{
|
||||
return_value = (d_tx.n_encoded_bits / 3) * 2;
|
||||
}
|
||||
else // si d_ntraceback == 10
|
||||
{
|
||||
return_value = (d_tx.n_encoded_bits / 4) * 3;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void decode_conv_viterbi() {
|
||||
|
||||
d_viterbi_chunks_init(state0);
|
||||
d_viterbi_chunks_init_sse2(metric0, path0);
|
||||
|
||||
int out_count = 0;
|
||||
decoded_count = 0;
|
||||
|
||||
int in_count = 0;
|
||||
int neededBits = NeededBits();
|
||||
while(decoded_count < neededBits)
|
||||
{
|
||||
if ((in_count % 4) == 0) //0 or 3
|
||||
{
|
||||
d_viterbi_butterfly2_sse2(&d_inbits[in_count & 0xfffffffc], metric0, metric1, path0, path1);
|
||||
|
||||
if ((in_count > 0) && (in_count % 16) == 8) // 8 or 11
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
d_viterbi_get_output_sse2(metric0, path0, d_ntraceback, &c);
|
||||
|
||||
if (d_init == 0)
|
||||
{
|
||||
if (out_count >= d_ntraceback)
|
||||
{
|
||||
for (int i= 0; i < 8; i++)
|
||||
{
|
||||
out_bytes_viterbi[(out_count - d_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1;
|
||||
decoded_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out_bytes_viterbi[out_count] = c;
|
||||
for (int i= 0; i < 8; i++)
|
||||
{
|
||||
out_bytes_viterbi[out_count * 8 + i] = (c >> (7 - i)) & 0x1;
|
||||
decoded_count++;
|
||||
}
|
||||
}
|
||||
out_count++;
|
||||
}
|
||||
}
|
||||
in_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void set_coding_rate()
|
||||
{
|
||||
switch(d_ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
// Code rate 1/2
|
||||
d_ntraceback = 5;
|
||||
d_puncture = d_puncture_1_2;
|
||||
d_k = 1;
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
// Code rate 2/3
|
||||
d_ntraceback = 9;
|
||||
d_puncture = d_puncture_2_3;
|
||||
d_k = 2;
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
// Code rate 3/4
|
||||
d_ntraceback = 10;
|
||||
d_puncture = d_puncture_3_4;
|
||||
d_k = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_conv() {
|
||||
decode_conv_viterbi();
|
||||
}
|
||||
|
||||
void descramble () {
|
||||
int state = 0;
|
||||
for(int i = 0; i < 7; i++) {
|
||||
if(out_bytes_viterbi[i]) {
|
||||
state |= 1 << (6 - i);
|
||||
}
|
||||
}
|
||||
|
||||
int feedback;
|
||||
|
||||
for(int i = 7; i < decoded_count; i++) {
|
||||
feedback = ((!!(state & 64))) ^ (!!(state & 8));
|
||||
out_bits[i] = feedback ^ (out_bytes_viterbi[i] & 0x1);
|
||||
state = ((state << 1) & 0x7e) | feedback;
|
||||
}
|
||||
|
||||
for(int i = 0; i < decoded_count; i++) {
|
||||
int bit = i % 8;
|
||||
int byte = i / 8;
|
||||
if(bit == 0) {
|
||||
out_bytes[byte] = 0;
|
||||
}
|
||||
|
||||
if(out_bits[i]) {
|
||||
out_bytes[byte] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_output() {
|
||||
|
||||
dout << std::endl;
|
||||
for(int i = 0; i < decoded_bits.size() / 8; i++) {
|
||||
dout << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " ";
|
||||
if(i % 16 == 15) {
|
||||
dout << std::endl;
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
for(int i = 0; i < decoded_bits.size() / 8; i++) {
|
||||
if((out_bytes[i] > 31) && (out_bytes[i] < 127)) {
|
||||
dout << ((char) out_bytes[i]);
|
||||
} else {
|
||||
dout << ".";
|
||||
}
|
||||
}
|
||||
dout << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
gr_complex sym[1000 * 48 * 100];
|
||||
vec bits;
|
||||
unsigned char* d_inbits;
|
||||
unsigned char d_inbits_punctured[1000 * 48];
|
||||
unsigned char d_tmp_inbits[1000 * 48];
|
||||
char out_bits[40000];
|
||||
char out_bytes[40000];
|
||||
char out_bytes_viterbi[40000 * 8];
|
||||
bvec decoded_bits;
|
||||
|
||||
int d_ntraceback;
|
||||
|
||||
// number of input bits in the convolutional encoder.
|
||||
int d_k;
|
||||
|
||||
const unsigned char * d_puncture;
|
||||
const unsigned char d_puncture_1_2[2] = {1, 1};
|
||||
const unsigned char d_puncture_2_3[4] = {1, 1, 1, 0};
|
||||
const unsigned char d_puncture_3_4[6] = {1, 1, 1, 0, 0, 1};
|
||||
|
||||
bool d_debug;
|
||||
bool d_log;
|
||||
tx_param d_tx;
|
||||
ofdm_param d_ofdm;
|
||||
int copied;
|
||||
bool d_frame_complete;
|
||||
};
|
||||
|
||||
ofdm_decode_mac::sptr
|
||||
ofdm_decode_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_decode_mac_impl(log, debug));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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_parse_mac.h>
|
||||
#include <ieee802-11/parse_mac.h>
|
||||
#include "utils.h"
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
@@ -23,24 +23,24 @@
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
class ofdm_parse_mac_impl : public ofdm_parse_mac {
|
||||
class parse_mac_impl : public parse_mac {
|
||||
|
||||
public:
|
||||
|
||||
ofdm_parse_mac_impl(bool log, bool debug) :
|
||||
block("ofdm_parse_mac",
|
||||
parse_mac_impl(bool log, bool debug) :
|
||||
block("parse_mac",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_log(log), d_last_seq_no(-1),
|
||||
d_debug(debug) {
|
||||
|
||||
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(&parse_mac_impl::parse, this, _1));
|
||||
|
||||
message_port_register_out(pmt::mp("fer"));
|
||||
}
|
||||
|
||||
~ofdm_parse_mac_impl() {
|
||||
~parse_mac_impl() {
|
||||
|
||||
}
|
||||
|
||||
@@ -358,9 +358,9 @@ private:
|
||||
int d_last_seq_no;
|
||||
};
|
||||
|
||||
ofdm_parse_mac::sptr
|
||||
ofdm_parse_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_parse_mac_impl(log, debug));
|
||||
parse_mac::sptr
|
||||
parse_mac::make(bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new parse_mac_impl(log, debug));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -15,32 +15,32 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "wifi_signal_field_impl.h"
|
||||
#include "signal_field_impl.h"
|
||||
#include "utils.h"
|
||||
#include <gnuradio/digital/lfsr.h>
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
wifi_signal_field::sptr
|
||||
wifi_signal_field::make() {
|
||||
return wifi_signal_field::sptr(new wifi_signal_field_impl());
|
||||
signal_field::sptr
|
||||
signal_field::make() {
|
||||
return signal_field::sptr(new signal_field_impl());
|
||||
}
|
||||
|
||||
wifi_signal_field::wifi_signal_field() : packet_header_default(48, "packet_len") {};
|
||||
signal_field::signal_field() : packet_header_default(48, "packet_len") {};
|
||||
|
||||
|
||||
wifi_signal_field_impl::wifi_signal_field_impl() : packet_header_default(48, "packet_len") {}
|
||||
signal_field_impl::signal_field_impl() : packet_header_default(48, "packet_len") {}
|
||||
|
||||
|
||||
wifi_signal_field_impl::~wifi_signal_field_impl() {}
|
||||
signal_field_impl::~signal_field_impl() {}
|
||||
|
||||
|
||||
int wifi_signal_field_impl::get_bit(int b, int i) {
|
||||
int signal_field_impl::get_bit(int b, int i) {
|
||||
return (b & (1 << i) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
void wifi_signal_field_impl::generate_signal_field(char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofdm_param &ofdm) {
|
||||
|
||||
//data bits of the signal header
|
||||
char *signal_header = (char *) malloc(sizeof(char) * 24);
|
||||
@@ -51,7 +51,7 @@ void wifi_signal_field_impl::generate_signal_field(char *out, tx_param &tx, ofdm
|
||||
//interleaving
|
||||
char *interleaved_signal_header = (char *) malloc(sizeof(char) * 48);
|
||||
|
||||
int length = tx.psdu_size;
|
||||
int length = frame.psdu_size;
|
||||
|
||||
// first 4 bits represent the modulation and coding scheme
|
||||
signal_header[ 0] = get_bit(ofdm.rate_field, 3);
|
||||
@@ -88,22 +88,22 @@ void wifi_signal_field_impl::generate_signal_field(char *out, tx_param &tx, ofdm
|
||||
}
|
||||
|
||||
ofdm_param signal_ofdm(BPSK_1_2);
|
||||
tx_param signal_tx(signal_ofdm, 3);
|
||||
signal_tx.n_data = 24;
|
||||
signal_tx.n_sym = 1;
|
||||
frame_param signal_param(signal_ofdm, 3);
|
||||
signal_param.n_data = 24;
|
||||
signal_param.n_sym = 1;
|
||||
|
||||
// convolutional encoding (scrambling is not needed)
|
||||
convolutional_encoding(signal_header, encoded_signal_header, signal_tx);
|
||||
convolutional_encoding(signal_header, encoded_signal_header, signal_param);
|
||||
// interleaving
|
||||
//interleave(encoded_signal_header, interleaved_signal_header, signal_tx, signal_ofdm);
|
||||
interleave(encoded_signal_header, out, signal_tx, signal_ofdm);
|
||||
//interleave(encoded_signal_header, interleaved_signal_header, signal_param, signal_ofdm);
|
||||
interleave(encoded_signal_header, out, signal_param, signal_ofdm);
|
||||
|
||||
free(signal_header);
|
||||
free(encoded_signal_header);
|
||||
free(interleaved_signal_header);
|
||||
}
|
||||
|
||||
bool wifi_signal_field_impl::header_formatter(long packet_len, unsigned char *out, const std::vector<tag_t> &tags)
|
||||
bool signal_field_impl::header_formatter(long packet_len, unsigned char *out, const std::vector<tag_t> &tags)
|
||||
{
|
||||
|
||||
bool encoding_found = false;
|
||||
@@ -128,13 +128,13 @@ bool wifi_signal_field_impl::header_formatter(long packet_len, unsigned char *ou
|
||||
}
|
||||
|
||||
ofdm_param ofdm((Encoding)encoding);
|
||||
tx_param tx(ofdm, len);
|
||||
frame_param frame(ofdm, len);
|
||||
|
||||
generate_signal_field((char*)out, tx, ofdm);
|
||||
generate_signal_field((char*)out, frame, ofdm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_signal_field_impl::header_parser(
|
||||
bool signal_field_impl::header_parser(
|
||||
const unsigned char *in, std::vector<tag_t> &tags) {
|
||||
|
||||
throw std::runtime_error("not implemented yet");
|
||||
@@ -15,20 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H
|
||||
#define INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H
|
||||
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H
|
||||
#define INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H
|
||||
|
||||
#include <ieee802-11/wifi_signal_field.h>
|
||||
#include <ieee802-11/signal_field.h>
|
||||
#include "utils.h"
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
|
||||
class wifi_signal_field_impl : public wifi_signal_field
|
||||
class signal_field_impl : public signal_field
|
||||
{
|
||||
public:
|
||||
wifi_signal_field_impl();
|
||||
~wifi_signal_field_impl();
|
||||
signal_field_impl();
|
||||
~signal_field_impl();
|
||||
|
||||
bool header_formatter(long packet_len, unsigned char *out,
|
||||
const std::vector<tag_t> &tags);
|
||||
@@ -37,11 +37,11 @@ public:
|
||||
std::vector<tag_t> &tags);
|
||||
private:
|
||||
int get_bit(int b, int i);
|
||||
void generate_signal_field(char *out, tx_param &tx, ofdm_param &ofdm);
|
||||
void generate_signal_field(char *out, frame_param &frame, ofdm_param &ofdm);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_WIFI_SIGNAL_FIELD_IMPL_H */
|
||||
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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_sync_long.h>
|
||||
#include <ieee802-11/sync_long.h>
|
||||
#include "utils.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/filter/fir_filter.h>
|
||||
@@ -31,10 +31,10 @@ bool compare_abs(const std::pair<gr_complex, int>& first, const std::pair<gr_com
|
||||
return abs(get<0>(first)) > abs(get<0>(second));
|
||||
}
|
||||
|
||||
class ofdm_sync_long_impl : public ofdm_sync_long {
|
||||
class sync_long_impl : public sync_long {
|
||||
|
||||
public:
|
||||
ofdm_sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("ofdm_sync_long",
|
||||
sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("sync_long",
|
||||
gr::io_signature::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||
d_fir(gr::filter::kernel::fir_filter_ccc(1, LONG)),
|
||||
@@ -48,7 +48,7 @@ ofdm_sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("ofd
|
||||
d_correlation = gr::fft::malloc_complex(8192);
|
||||
}
|
||||
|
||||
~ofdm_sync_long_impl(){
|
||||
~sync_long_impl(){
|
||||
gr::fft::free(d_correlation);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ int general_work (int noutput, gr_vector_int& ninput_items,
|
||||
|
||||
if(!rel) {
|
||||
add_item_tag(0, nitems_written(0),
|
||||
pmt::string_to_symbol("ofdm_start"),
|
||||
pmt::string_to_symbol("wifi_start"),
|
||||
pmt::PMT_T,
|
||||
pmt::string_to_symbol(name()));
|
||||
}
|
||||
@@ -235,12 +235,12 @@ private:
|
||||
static const std::vector<gr_complex> LONG;
|
||||
};
|
||||
|
||||
ofdm_sync_long::sptr
|
||||
ofdm_sync_long::make(unsigned int sync_length, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_sync_long_impl(sync_length, log, debug));
|
||||
sync_long::sptr
|
||||
sync_long::make(unsigned int sync_length, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, debug));
|
||||
}
|
||||
|
||||
const std::vector<gr_complex> ofdm_sync_long_impl::LONG = {
|
||||
const std::vector<gr_complex> sync_long_impl::LONG = {
|
||||
|
||||
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),
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
|
||||
* Copyright (C) 2013, 2016 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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_sync_short.h>
|
||||
#include <ieee802-11/sync_short.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include "utils.h"
|
||||
|
||||
@@ -25,11 +25,11 @@ using namespace gr::ieee802_11;
|
||||
static const int MIN_GAP = 480;
|
||||
static const int MAX_SAMPLES = 540 * 80;
|
||||
|
||||
class ofdm_sync_short_impl : public ofdm_sync_short {
|
||||
class sync_short_impl : public sync_short {
|
||||
|
||||
public:
|
||||
ofdm_sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) :
|
||||
block("ofdm_sync_short",
|
||||
sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) :
|
||||
block("sync_short",
|
||||
gr::io_signature::make3(3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||
d_log(log),
|
||||
@@ -131,7 +131,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
|
||||
void insert_tag(uint64_t item) {
|
||||
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("wifi_start");
|
||||
const pmt::pmt_t value = pmt::PMT_T;
|
||||
const pmt::pmt_t srcid = pmt::string_to_symbol(name());
|
||||
add_item_tag(0, item, key, value, srcid);
|
||||
@@ -148,7 +148,7 @@ private:
|
||||
const unsigned int MIN_PLATEAU;
|
||||
};
|
||||
|
||||
ofdm_sync_short::sptr
|
||||
ofdm_sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold, min_plateau, log, debug));
|
||||
sync_short::sptr
|
||||
sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) {
|
||||
return gnuradio::get_initial_sptr(new sync_short_impl(threshold, min_plateau, log, debug));
|
||||
}
|
||||
+19
-713
@@ -153,7 +153,7 @@ ofdm_param::print() {
|
||||
}
|
||||
|
||||
|
||||
tx_param::tx_param(ofdm_param &ofdm, int psdu_length) {
|
||||
frame_param::frame_param(ofdm_param &ofdm, int psdu_length) {
|
||||
|
||||
psdu_size = psdu_length;
|
||||
|
||||
@@ -169,8 +169,8 @@ tx_param::tx_param(ofdm_param &ofdm, int psdu_length) {
|
||||
n_encoded_bits = n_sym * ofdm.n_cbps;
|
||||
}
|
||||
void
|
||||
tx_param::print() {
|
||||
std::cout << "TX Parameters:" << std::endl;
|
||||
frame_param::print() {
|
||||
std::cout << "FRAME 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;
|
||||
@@ -178,12 +178,12 @@ tx_param::print() {
|
||||
}
|
||||
|
||||
|
||||
void scramble(const char *in, char *out, tx_param &tx, char initial_state) {
|
||||
void scramble(const char *in, char *out, frame_param &frame, char initial_state) {
|
||||
|
||||
int state = initial_state;
|
||||
int feedback;
|
||||
|
||||
for (int i = 0; i < tx.n_data; i++) {
|
||||
for (int i = 0; i < frame.n_data; i++) {
|
||||
|
||||
feedback = (!!(state & 64)) ^ (!!(state & 8));
|
||||
out[i] = feedback ^ in[i];
|
||||
@@ -192,8 +192,8 @@ void scramble(const char *in, char *out, tx_param &tx, char initial_state) {
|
||||
}
|
||||
|
||||
|
||||
void reset_tail_bits(char *scrambled_data, tx_param &tx) {
|
||||
memset(scrambled_data + tx.n_data - tx.n_pad - 6, 0, 6 * sizeof(char));
|
||||
void reset_tail_bits(char *scrambled_data, frame_param &frame) {
|
||||
memset(scrambled_data + frame.n_data - frame.n_pad - 6, 0, 6 * sizeof(char));
|
||||
}
|
||||
|
||||
|
||||
@@ -208,11 +208,11 @@ int ones(int n) {
|
||||
}
|
||||
|
||||
|
||||
void convolutional_encoding(const char *in, char *out, tx_param &tx) {
|
||||
void convolutional_encoding(const char *in, char *out, frame_param &frame) {
|
||||
|
||||
int state = 0;
|
||||
|
||||
for(int i = 0; i < tx.n_data; i++) {
|
||||
for(int i = 0; i < frame.n_data; i++) {
|
||||
assert(in[i] == 0 || in[i] == 1);
|
||||
state = ((state << 1) & 0x7e) | in[i];
|
||||
out[i * 2] = ones(state & 0155) % 2;
|
||||
@@ -221,11 +221,11 @@ void convolutional_encoding(const char *in, char *out, tx_param &tx) {
|
||||
}
|
||||
|
||||
|
||||
void puncturing(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
void puncturing(const char *in, char *out, frame_param &frame, ofdm_param &ofdm) {
|
||||
|
||||
int mod;
|
||||
|
||||
for (int i = 0; i < tx.n_data * 2; i++) {
|
||||
for (int i = 0; i < frame.n_data * 2; i++) {
|
||||
switch(ofdm.encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
@@ -259,7 +259,7 @@ void puncturing(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
}
|
||||
|
||||
|
||||
void interleave(const char *in, char *out, tx_param &tx, ofdm_param &ofdm, bool reverse) {
|
||||
void interleave(const char *in, char *out, frame_param &frame, ofdm_param &ofdm, bool reverse) {
|
||||
|
||||
int n_cbps = ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
@@ -274,7 +274,7 @@ void interleave(const char *in, char *out, tx_param &tx, ofdm_param &ofdm, bool
|
||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||
}
|
||||
|
||||
for(int i = 0; i < tx.n_sym; i++) {
|
||||
for(int i = 0; i < frame.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];
|
||||
@@ -286,7 +286,7 @@ void interleave(const char *in, char *out, tx_param &tx, ofdm_param &ofdm, bool
|
||||
}
|
||||
|
||||
|
||||
void interleave(const double *in, double *out, tx_param &tx, ofdm_param &ofdm, bool reverse) {
|
||||
void interleave(const double *in, double *out, frame_param &frame, ofdm_param &ofdm, bool reverse) {
|
||||
|
||||
int n_cbps = ofdm.n_cbps;
|
||||
int first[n_cbps];
|
||||
@@ -301,7 +301,7 @@ void interleave(const double *in, double *out, tx_param &tx, ofdm_param &ofdm, b
|
||||
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
|
||||
}
|
||||
|
||||
for(int i = 0; i < tx.n_sym; i++) {
|
||||
for(int i = 0; i < frame.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];
|
||||
@@ -313,9 +313,9 @@ void interleave(const double *in, double *out, tx_param &tx, ofdm_param &ofdm, b
|
||||
}
|
||||
|
||||
|
||||
void split_symbols(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
void split_symbols(const char *in, char *out, frame_param &frame, ofdm_param &ofdm) {
|
||||
|
||||
int symbols = tx.n_sym * 48;
|
||||
int symbols = frame.n_sym * 48;
|
||||
|
||||
for (int i = 0; i < symbols; i++) {
|
||||
out[i] = 0;
|
||||
@@ -328,709 +328,15 @@ void split_symbols(const char *in, char *out, tx_param &tx, ofdm_param &ofdm) {
|
||||
}
|
||||
|
||||
|
||||
void generate_bits(const char *psdu, char *data_bits, tx_param &tx) {
|
||||
void generate_bits(const char *psdu, char *data_bits, frame_param &frame) {
|
||||
|
||||
// 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 i = 0; i < frame.psdu_size; i++) {
|
||||
for(int b = 0; b < 8; b++) {
|
||||
data_bits[i * 8 + b] = !!(psdu[i] & (1 << b));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Here starts the SSE2 Viterbi convolutional decoder implementation */
|
||||
/*
|
||||
* Copyright 1995 Phil Karn, KA9Q
|
||||
* Copyright 2008 Free Software Foundation, Inc.
|
||||
* 2014 Added SSE2 implementation Bogdan Diaconescu
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Viterbi decoder for K=7 rate=1/2 convolutional code
|
||||
* Some modifications from original Karn code by Matt Ettus
|
||||
* Major modifications by adding SSE2 code by Bogdan Diaconescu
|
||||
*/
|
||||
#include <xmmintrin.h>
|
||||
|
||||
/* The two generator polynomials for the NASA Standard K=7 code.
|
||||
* Since these polynomials are known to be optimal for this constraint
|
||||
* length there is not much point in changing them. But if you do, you
|
||||
* will have to regenerate the BUTTERFLY macro calls in viterbi()
|
||||
*/
|
||||
#define POLYA 0x6d
|
||||
#define POLYB 0x4f
|
||||
|
||||
/* The basic Viterbi decoder operation, called a "butterfly"
|
||||
* operation because of the way it looks on a trellis diagram. Each
|
||||
* butterfly involves an Add-Compare-Select (ACS) operation on the two nodes
|
||||
* where the 0 and 1 paths from the current node merge at the next step of
|
||||
* the trellis.
|
||||
*
|
||||
* The code polynomials are assumed to have 1's on both ends. Given a
|
||||
* function encode_state() that returns the two symbols for a given
|
||||
* encoder state in the low two bits, such a code will have the following
|
||||
* identities for even 'n' < 64:
|
||||
*
|
||||
* encode_state(n) = encode_state(n+65)
|
||||
* encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n))
|
||||
*
|
||||
* Any convolutional code you would actually want to use will have
|
||||
* these properties, so these assumptions aren't too limiting.
|
||||
*
|
||||
* Doing this as a macro lets the compiler evaluate at compile time the
|
||||
* many expressions that depend on the loop index and encoder state and
|
||||
* emit them as immediate arguments.
|
||||
* This makes an enormous difference on register-starved machines such
|
||||
* as the Intel x86 family where evaluating these expressions at runtime
|
||||
* would spill over into memory.
|
||||
*/
|
||||
|
||||
|
||||
static union branchtab27 { unsigned char c[32]; __m128i v[2];} Branchtab27_sse2[2];
|
||||
|
||||
// Maximum number of traceback bytes
|
||||
#define TRACEBACK_MAX 24
|
||||
// Metrics for each state
|
||||
static unsigned char mmresult[64] __attribute__((aligned(16))) = {0};
|
||||
// Paths for each state
|
||||
static unsigned char ppresult[TRACEBACK_MAX][64] __attribute__((aligned(16))) = {{0,0}};
|
||||
// Position in circular buffer where the current decoded byte is stored
|
||||
static int store_pos = 0;
|
||||
|
||||
#define BUTTERFLY(i,sym) { \
|
||||
int m0,m1,m2,m3;\
|
||||
/* ACS for 0 branch */\
|
||||
m0 = state[i].metric + mets[sym]; /* 2*i */\
|
||||
m1 = state[i+32].metric + mets[3 ^ sym]; /* 2*i + 64 */\
|
||||
if(m0 > m1){\
|
||||
next[2*i].metric = m0;\
|
||||
next[2*i].path = state[i].path << 1;\
|
||||
} else {\
|
||||
next[2*i].metric = m1;\
|
||||
next[2*i].path = (state[i+32].path << 1)|1;\
|
||||
}\
|
||||
/* ACS for 1 branch */\
|
||||
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */\
|
||||
m3 = state[i+32].metric + mets[sym]; /* 2*i + 65 */\
|
||||
if(m2 > m3){\
|
||||
next[2*i+1].metric = m2;\
|
||||
next[2*i+1].path = state[i].path << 1;\
|
||||
} else {\
|
||||
next[2*i+1].metric = m3;\
|
||||
next[2*i+1].path = (state[i+32].path << 1)|1;\
|
||||
}\
|
||||
}
|
||||
|
||||
unsigned char d_Partab[] = {
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
};/* Parity lookup table */
|
||||
|
||||
/* Convolutionally encode data into binary symbols */
|
||||
unsigned char
|
||||
d_encode(unsigned char *symbols,
|
||||
unsigned char *data,
|
||||
unsigned int nbytes,
|
||||
unsigned char encstate)
|
||||
{
|
||||
int i;
|
||||
|
||||
while(nbytes-- != 0){
|
||||
for(i=7;i>=0;i--){
|
||||
encstate = (encstate << 1) | ((*data >> i) & 1);
|
||||
*symbols++ = d_Partab[encstate & POLYA];
|
||||
*symbols++ = d_Partab[encstate & POLYB];
|
||||
}
|
||||
data++;
|
||||
}
|
||||
|
||||
return encstate;
|
||||
}
|
||||
|
||||
/* Viterbi decoder */
|
||||
int
|
||||
d_viterbi(unsigned long *metric, /* Final path metric (returned value) */
|
||||
unsigned char *data, /* Decoded output data */
|
||||
unsigned char *symbols, /* Raw deinterleaved input symbols */
|
||||
unsigned int nbits, /* Number of output bits */
|
||||
int mettab[2][256] /* Metric table, [sent sym][rx symbol] */
|
||||
){
|
||||
unsigned int bitcnt = 0;
|
||||
int mets[4];
|
||||
long bestmetric;
|
||||
int beststate,i;
|
||||
struct viterbi_state state0[64],state1[64],*state,*next;
|
||||
|
||||
state = state0;
|
||||
next = state1;
|
||||
|
||||
/* Initialize starting metrics to prefer 0 state */
|
||||
state[0].metric = 0;
|
||||
for(i=1;i<64;i++)
|
||||
state[i].metric = -999999;
|
||||
state[0].path = 0;
|
||||
|
||||
for(bitcnt = 0;bitcnt < nbits;bitcnt++){
|
||||
/* Read input symbol pair and compute all possible branch
|
||||
* metrics
|
||||
*/
|
||||
mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
|
||||
mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
|
||||
mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
|
||||
mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
|
||||
symbols += 2;
|
||||
|
||||
BUTTERFLY(0,0); BUTTERFLY(1,1); BUTTERFLY(2,3); BUTTERFLY(3,2);
|
||||
BUTTERFLY(4,3); BUTTERFLY(5,2); BUTTERFLY(6,0); BUTTERFLY(7,1);
|
||||
BUTTERFLY(8,0); BUTTERFLY(9,1); BUTTERFLY(10,3); BUTTERFLY(11,2);
|
||||
BUTTERFLY(12,3); BUTTERFLY(13,2); BUTTERFLY(14,0); BUTTERFLY(15,1);
|
||||
BUTTERFLY(16,2); BUTTERFLY(17,3); BUTTERFLY(18,1); BUTTERFLY(19,0);
|
||||
BUTTERFLY(20,1); BUTTERFLY(21,0); BUTTERFLY(22,2); BUTTERFLY(23,3);
|
||||
BUTTERFLY(24,2); BUTTERFLY(25,3); BUTTERFLY(26,1); BUTTERFLY(27,0);
|
||||
BUTTERFLY(28,1); BUTTERFLY(29,0); BUTTERFLY(30,2); BUTTERFLY(31,3);
|
||||
|
||||
/* Swap current and next states */
|
||||
if(bitcnt & 1){
|
||||
state = state0;
|
||||
next = state1;
|
||||
} else {
|
||||
state = state1;
|
||||
next = state0;
|
||||
}
|
||||
// ETTUS
|
||||
//if(bitcnt > nbits-7){
|
||||
/* In tail, poison non-zero nodes */
|
||||
//for(i=1;i<64;i += 2)
|
||||
// state[i].metric = -9999999;
|
||||
//}
|
||||
/* Produce output every 8 bits once path memory is full */
|
||||
if((bitcnt % 8) == 5 && bitcnt > 32){
|
||||
/* Find current best path */
|
||||
bestmetric = state[0].metric;
|
||||
beststate = 0;
|
||||
for(i=1;i<64;i++){
|
||||
if(state[i].metric > bestmetric){
|
||||
bestmetric = state[i].metric;
|
||||
beststate = i;
|
||||
}
|
||||
}
|
||||
#ifdef notdef
|
||||
printf("metrics[%d] = %d state = %lx\n",beststate,
|
||||
state[beststate].metric,state[beststate].path);
|
||||
#endif
|
||||
*data++ = state[beststate].path >> 24;
|
||||
}
|
||||
|
||||
}
|
||||
/* Output remaining bits from 0 state */
|
||||
// ETTUS Find best state instead
|
||||
bestmetric = state[0].metric;
|
||||
beststate = 0;
|
||||
for(i=1;i<64;i++){
|
||||
if(state[i].metric > bestmetric){
|
||||
bestmetric = state[i].metric;
|
||||
beststate = i;
|
||||
}
|
||||
}
|
||||
if((i = bitcnt % 8) != 6)
|
||||
state[beststate].path <<= 6-i;
|
||||
|
||||
*data++ = state[beststate].path >> 24;
|
||||
*data++ = state[beststate].path >> 16;
|
||||
*data++ = state[beststate].path >> 8;
|
||||
*data = state[beststate].path;
|
||||
//printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric);
|
||||
*metric = state[beststate].metric;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
d_viterbi_chunks_init(struct viterbi_state* state) {
|
||||
// Initialize starting metrics to prefer 0 state
|
||||
int i;
|
||||
state[0].metric = 0;
|
||||
state[0].path = 0;
|
||||
for(i=1;i<64;i++)
|
||||
{
|
||||
state[i].metric = 0;//-999999;
|
||||
state[i].path = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
d_viterbi_chunks_init_sse2(__m128i *mm0, __m128i *pp0) {
|
||||
// Initialize starting metrics to prefer 0 state
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
mm0[i] = _mm_setzero_si128();
|
||||
pp0[i] = _mm_setzero_si128();
|
||||
}
|
||||
|
||||
int polys[2] = { POLYA, POLYB };
|
||||
for(i=0; i < 32; i++)
|
||||
{
|
||||
Branchtab27_sse2[0].c[i] = (polys[0] < 0) ^ d_Partab[(2*i) & abs(polys[0])] ? 1 : 0;
|
||||
Branchtab27_sse2[1].c[i] = (polys[1] < 0) ^ d_Partab[(2*i) & abs(polys[1])] ? 1 : 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
mmresult[i] = 0;
|
||||
for (j = 0; j < TRACEBACK_MAX; j++)
|
||||
ppresult[j][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
d_viterbi_butterfly8(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1)
|
||||
{
|
||||
unsigned int bitcnt;
|
||||
int mets[4];
|
||||
|
||||
struct viterbi_state *state, *next;
|
||||
state = state0;
|
||||
next = state1;
|
||||
// Operate on 16 symbols (8 bits) at a time
|
||||
for(bitcnt = 0;bitcnt < 8;bitcnt++){
|
||||
// Read input symbol pair and compute all possible branch metrics
|
||||
mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
|
||||
mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
|
||||
mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
|
||||
mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
|
||||
symbols += 2;
|
||||
|
||||
// These macro calls were generated by genbut.c
|
||||
BUTTERFLY(0,0); BUTTERFLY(1,1); BUTTERFLY(2,3); BUTTERFLY(3,2);
|
||||
BUTTERFLY(4,3); BUTTERFLY(5,2); BUTTERFLY(6,0); BUTTERFLY(7,1);
|
||||
BUTTERFLY(8,0); BUTTERFLY(9,1); BUTTERFLY(10,3); BUTTERFLY(11,2);
|
||||
BUTTERFLY(12,3); BUTTERFLY(13,2); BUTTERFLY(14,0); BUTTERFLY(15,1);
|
||||
BUTTERFLY(16,2); BUTTERFLY(17,3); BUTTERFLY(18,1); BUTTERFLY(19,0);
|
||||
BUTTERFLY(20,1); BUTTERFLY(21,0); BUTTERFLY(22,2); BUTTERFLY(23,3);
|
||||
BUTTERFLY(24,2); BUTTERFLY(25,3); BUTTERFLY(26,1); BUTTERFLY(27,0);
|
||||
BUTTERFLY(28,1); BUTTERFLY(29,0); BUTTERFLY(30,2); BUTTERFLY(31,3);
|
||||
|
||||
// Swap current and next states
|
||||
if(bitcnt & 1){
|
||||
state = state0;
|
||||
next = state1;
|
||||
} else {
|
||||
state = state1;
|
||||
next = state0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
d_viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1)
|
||||
{
|
||||
int mets[4];
|
||||
|
||||
struct viterbi_state *state, *next;
|
||||
state = state0;
|
||||
next = state1;
|
||||
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
|
||||
// Read input symbol pair and compute all possible branch metrics
|
||||
#if 0
|
||||
if (symbols[0] == 2)
|
||||
{
|
||||
mets[0] = mettab[0][symbols[1]];
|
||||
mets[1] = mettab[1][symbols[1]];
|
||||
mets[2] = mettab[0][symbols[1]];
|
||||
mets[3] = mettab[1][symbols[1]];
|
||||
}
|
||||
else if (symbols[1] == 2)
|
||||
{
|
||||
mets[0] = mettab[0][symbols[0]];
|
||||
mets[1] = mettab[1][symbols[0]];
|
||||
mets[2] = mettab[0][symbols[0]];
|
||||
mets[3] = mettab[1][symbols[0]];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
|
||||
mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
|
||||
mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
|
||||
mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
|
||||
}
|
||||
|
||||
// These macro calls were generated by genbut.c
|
||||
BUTTERFLY(0,0); BUTTERFLY(1,1); BUTTERFLY(2,3); BUTTERFLY(3,2);
|
||||
BUTTERFLY(4,3); BUTTERFLY(5,2); BUTTERFLY(6,0); BUTTERFLY(7,1);
|
||||
BUTTERFLY(8,0); BUTTERFLY(9,1); BUTTERFLY(10,3); BUTTERFLY(11,2);
|
||||
BUTTERFLY(12,3); BUTTERFLY(13,2); BUTTERFLY(14,0); BUTTERFLY(15,1);
|
||||
BUTTERFLY(16,2); BUTTERFLY(17,3); BUTTERFLY(18,1); BUTTERFLY(19,0);
|
||||
BUTTERFLY(20,1); BUTTERFLY(21,0); BUTTERFLY(22,2); BUTTERFLY(23,3);
|
||||
BUTTERFLY(24,2); BUTTERFLY(25,3); BUTTERFLY(26,1); BUTTERFLY(27,0);
|
||||
BUTTERFLY(28,1); BUTTERFLY(29,0); BUTTERFLY(30,2); BUTTERFLY(31,3);
|
||||
|
||||
state = state1;
|
||||
next = state0;
|
||||
|
||||
// Read input symbol pair and compute all possible branch metrics
|
||||
|
||||
#if 0
|
||||
if (symbols[2] == 2)
|
||||
{
|
||||
mets[0] = mettab[0][symbols[3]];
|
||||
mets[1] = mettab[1][symbols[3]];
|
||||
mets[2] = mettab[0][symbols[3]];
|
||||
mets[3] = mettab[1][symbols[3]];
|
||||
}
|
||||
else if (symbols[3] == 2)
|
||||
{
|
||||
mets[0] = mettab[0][symbols[2]];
|
||||
mets[1] = mettab[1][symbols[2]];
|
||||
mets[2] = mettab[0][symbols[2]];
|
||||
mets[3] = mettab[1][symbols[2]];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mets[0] = mettab[0][symbols[2]] + mettab[0][symbols[3]];
|
||||
mets[1] = mettab[0][symbols[2]] + mettab[1][symbols[3]];
|
||||
mets[2] = mettab[1][symbols[2]] + mettab[0][symbols[3]];
|
||||
mets[3] = mettab[1][symbols[2]] + mettab[1][symbols[3]];
|
||||
}
|
||||
|
||||
// These macro calls were generated by genbut.c
|
||||
BUTTERFLY(0,0); BUTTERFLY(1,1); BUTTERFLY(2,3); BUTTERFLY(3,2);
|
||||
BUTTERFLY(4,3); BUTTERFLY(5,2); BUTTERFLY(6,0); BUTTERFLY(7,1);
|
||||
BUTTERFLY(8,0); BUTTERFLY(9,1); BUTTERFLY(10,3); BUTTERFLY(11,2);
|
||||
BUTTERFLY(12,3); BUTTERFLY(13,2); BUTTERFLY(14,0); BUTTERFLY(15,1);
|
||||
BUTTERFLY(16,2); BUTTERFLY(17,3); BUTTERFLY(18,1); BUTTERFLY(19,0);
|
||||
BUTTERFLY(20,1); BUTTERFLY(21,0); BUTTERFLY(22,2); BUTTERFLY(23,3);
|
||||
BUTTERFLY(24,2); BUTTERFLY(25,3); BUTTERFLY(26,1); BUTTERFLY(27,0);
|
||||
BUTTERFLY(28,1); BUTTERFLY(29,0); BUTTERFLY(30,2); BUTTERFLY(31,3);
|
||||
}
|
||||
|
||||
void
|
||||
d_viterbi_butterfly2_sse2(unsigned char *symbols, __m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1)
|
||||
{
|
||||
int i;
|
||||
|
||||
__m128i *metric0, *metric1;
|
||||
__m128i *path0, *path1;
|
||||
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
|
||||
__m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1;
|
||||
__m128i metsv, metsvm;
|
||||
__m128i shift0, shift1;
|
||||
__m128i tmp0, tmp1;
|
||||
__m128i sym0v, sym1v;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[0]);
|
||||
sym1v = _mm_set1_epi8(symbols[1]);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (symbols[0] == 2)
|
||||
{
|
||||
metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
}
|
||||
else if (symbols[1] == 2)
|
||||
{
|
||||
metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
}
|
||||
else
|
||||
{
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
}
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
|
||||
metric0 = mm1;
|
||||
path0 = pp1;
|
||||
metric1 = mm0;
|
||||
path1 = pp0;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[2]);
|
||||
sym1v = _mm_set1_epi8(symbols[3]);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (symbols[2] == 2)
|
||||
{
|
||||
metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
}
|
||||
else if (symbols[3] == 2)
|
||||
{
|
||||
metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
}
|
||||
else
|
||||
{
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
}
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
d_viterbi_butterfly_sse2(unsigned char *symbols, __m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1)
|
||||
{
|
||||
int i;
|
||||
|
||||
__m128i *metric0, *metric1;
|
||||
__m128i *path0, *path1;
|
||||
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
printf("symbols[%i]: %i\n", i, symbols[i]);
|
||||
|
||||
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
|
||||
__m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1;
|
||||
__m128i metsv, metsvm;
|
||||
__m128i shift0, shift1;
|
||||
__m128i tmp0, tmp1;
|
||||
__m128i sym0v, sym1v;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[0]);
|
||||
sym1v = _mm_set1_epi8(symbols[1]);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
#if 1
|
||||
if (symbols[0] == 2)
|
||||
{
|
||||
metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v);
|
||||
}
|
||||
else if (symbols[1] == 0)
|
||||
{
|
||||
metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v));
|
||||
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
mm0[i] = metric1[i];
|
||||
pp0[i] = path1[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned char
|
||||
d_viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf) {
|
||||
// Produce output every 8 bits once path memory is full
|
||||
// if((bitcnt % 8) == 5 && bitcnt > 32) {
|
||||
|
||||
// Find current best path
|
||||
unsigned int i, beststate = 0;
|
||||
int bestmetric;
|
||||
|
||||
bestmetric = state[0].metric;
|
||||
beststate = 0;
|
||||
for(i=1;i<64;i++)
|
||||
{
|
||||
if(state[i].metric > bestmetric) {
|
||||
bestmetric = state[i].metric;
|
||||
beststate = i;
|
||||
}
|
||||
}
|
||||
|
||||
*outbuf = state[beststate].path >> 24;
|
||||
|
||||
return bestmetric;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
d_viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0, int ntraceback, unsigned char *outbuf) {
|
||||
// Find current best path
|
||||
int i;
|
||||
int bestmetric, minmetric;
|
||||
int beststate = 0;
|
||||
int pos = 0;
|
||||
|
||||
// Implement a circular buffer with the last ntraceback paths
|
||||
store_pos = (store_pos + 1) % ntraceback;
|
||||
|
||||
// TODO - find another way to extract the value
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
_mm_store_si128((__m128i *) &mmresult[i*16], mm0[i]);
|
||||
_mm_store_si128((__m128i *) &ppresult[store_pos][i*16], pp0[i]);
|
||||
}
|
||||
|
||||
// Find out the best final state
|
||||
bestmetric = mmresult[beststate];
|
||||
minmetric = mmresult[beststate];
|
||||
|
||||
for (i = 1; i < 64; i++)
|
||||
{
|
||||
if (mmresult[i] > bestmetric)
|
||||
{
|
||||
bestmetric = mmresult[i];
|
||||
beststate = i;
|
||||
}
|
||||
if (mmresult[i] < minmetric)
|
||||
minmetric = mmresult[i];
|
||||
}
|
||||
|
||||
// Trace back
|
||||
for (i = 0, pos = store_pos; i < (ntraceback - 1); i++)
|
||||
{
|
||||
// Obtain the state from the output bits
|
||||
// by clocking in the output bits in reverse order.
|
||||
// The state has only 6 bits
|
||||
beststate = ppresult[pos][beststate] >> 2;
|
||||
pos = (pos - 1 + ntraceback) % ntraceback;
|
||||
}
|
||||
|
||||
// Store output byte
|
||||
*outbuf = ppresult[pos][beststate];
|
||||
|
||||
// Zero out the path variable
|
||||
// and prevent metric overflow
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
pp0[i] = _mm_setzero_si128();
|
||||
mm0[i] = _mm_sub_epi8(mm0[i], _mm_set1_epi8(minmetric));
|
||||
}
|
||||
|
||||
return bestmetric;
|
||||
}
|
||||
/* end of new functions */
|
||||
|
||||
+15
-80
@@ -14,18 +14,15 @@
|
||||
* 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
|
||||
#ifndef INCLUDED_IEEE802_11_UTILS_H
|
||||
#define INCLUDED_IEEE802_11_UTILS_H
|
||||
|
||||
#include <ieee802-11/api.h>
|
||||
#include <ieee802-11/ofdm_mapper.h>
|
||||
#include <ieee802-11/mapper.h>
|
||||
#include <gnuradio/config.h>
|
||||
#include <cinttypes>
|
||||
#include <iostream>
|
||||
|
||||
// Needed for the SSE2 Viterbi decoder
|
||||
#include <xmmintrin.h>
|
||||
|
||||
const int MAX_SYM = 520; // enough for 1500 byte BPSK 1/2
|
||||
const int MAX_BITS = 1550 * 8 * 2;
|
||||
|
||||
@@ -54,7 +51,7 @@ struct mac_header {
|
||||
}__attribute__((packed));
|
||||
|
||||
/**
|
||||
* OFDM parameters
|
||||
* WIFI parameters
|
||||
*/
|
||||
class ofdm_param {
|
||||
public:
|
||||
@@ -77,9 +74,9 @@ public:
|
||||
/**
|
||||
* packet specific parameters
|
||||
*/
|
||||
class tx_param {
|
||||
class frame_param {
|
||||
public:
|
||||
tx_param(ofdm_param &ofdm, int psdu_length);
|
||||
frame_param(ofdm_param &ofdm, int psdu_length);
|
||||
// PSDU size in bytes
|
||||
int psdu_size;
|
||||
// number of OFDM symbols (17-11)
|
||||
@@ -108,81 +105,19 @@ public:
|
||||
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 scramble(const char *input, char *out, frame_param &frame, char initial_state);
|
||||
|
||||
void reset_tail_bits(char *scrambled_data, tx_param &tx);
|
||||
void reset_tail_bits(char *scrambled_data, frame_param &frame);
|
||||
|
||||
void convolutional_encoding(const char *input, char *out, tx_param &tx);
|
||||
void convolutional_encoding(const char *input, char *out, frame_param &frame);
|
||||
|
||||
void puncturing(const char *input, char *out, tx_param &tx, ofdm_param &ofdm);
|
||||
void puncturing(const char *input, char *out, frame_param &frame, 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 interleave(const char *input, char *out, frame_param &frame, ofdm_param &ofdm, bool reverse = false);
|
||||
void interleave(const double *input, double *out, frame_param &frame, ofdm_param &ofdm, bool reverse = false);
|
||||
|
||||
void split_symbols(const char *input, char *out, tx_param &tx, ofdm_param &ofdm);
|
||||
void split_symbols(const char *input, char *out, frame_param &frame, ofdm_param &ofdm);
|
||||
|
||||
void generate_bits(const char *psdu, char *data_bits, tx_param &tx);
|
||||
void generate_bits(const char *psdu, char *data_bits, frame_param &frame);
|
||||
|
||||
/* New functions for the SSE2 Convolutional Decoder */
|
||||
|
||||
/* This Viterbi decoder was taken from the gr-dvbt module of
|
||||
* GNU Radio. It is an SSE2 version of the Viterbi Decoder
|
||||
* created by Phil Karn. The SSE2 version was made by Bogdan
|
||||
* Diaconescu. For more info see: gr-dvbt/lib/d_viterbi.h
|
||||
*/
|
||||
|
||||
|
||||
struct viterbi_state {
|
||||
unsigned long path; /* Decoded path to this state */
|
||||
long metric; /* Cumulative metric to this state */
|
||||
|
||||
/* vector implementation */
|
||||
__m128i pp; /* Decoded path to this state */
|
||||
__m128i mm; /* Cumulative metric to this state */
|
||||
};
|
||||
|
||||
int d_gen_met(int mettab[2][256], /* Metric table */
|
||||
int amp, /* Signal amplitude */
|
||||
double esn0, /* Es/N0 ratio in dB */
|
||||
double bias, /* Metric bias */
|
||||
int scale); /* Scale factor */
|
||||
|
||||
unsigned char
|
||||
d_encode(unsigned char *symbols, unsigned char *data,
|
||||
unsigned int nbytes,unsigned char encstate);
|
||||
|
||||
void
|
||||
d_viterbi_chunks_init(struct viterbi_state* state);
|
||||
|
||||
void
|
||||
d_viterbi_chunks_init_sse2(__m128i *mm0, __m128i *pp0);
|
||||
|
||||
void
|
||||
d_viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1);
|
||||
|
||||
void
|
||||
d_viterbi_butterfly2_sse2(unsigned char *symbols, __m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
|
||||
|
||||
void
|
||||
d_viterbi_butterfly_sse2(unsigned char *symbols, __m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
|
||||
|
||||
unsigned char
|
||||
d_viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf);
|
||||
|
||||
unsigned char
|
||||
d_viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0, int ntraceback, unsigned char *outbuf);
|
||||
|
||||
|
||||
int
|
||||
d_viterbi(unsigned long *metric, /* Final path metric (returned value) */
|
||||
unsigned char *data, /* Decoded output data */
|
||||
unsigned char *symbols, /* Raw deinterleaved input symbols */
|
||||
unsigned int nbits, /* Number of output bits */
|
||||
int mettab[2][256] /* Metric table, [sent sym][rx symbol] */
|
||||
);
|
||||
|
||||
|
||||
/* End of added functions */
|
||||
|
||||
|
||||
#endif /* INCLUDED_IEEE802_11_OFDM_UTILS_H */
|
||||
#endif /* INCLUDED_IEEE802_11_UTILS_H */
|
||||
|
||||
@@ -39,4 +39,3 @@ include(GrTest)
|
||||
|
||||
set(GR_TEST_TARGET_DEPS gnuradio-ieee802-11)
|
||||
set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
|
||||
#GR_ADD_TEST(qa_howto ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_howto.py)
|
||||
|
||||
+29
-29
@@ -28,15 +28,15 @@
|
||||
#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_signal.h"
|
||||
#include "ieee802-11/ofdm_equalize_symbols.h"
|
||||
#include "ieee802-11/ofdm_mac.h"
|
||||
#include "ieee802-11/ofdm_mapper.h"
|
||||
#include "ieee802-11/ofdm_parse_mac.h"
|
||||
#include "ieee802-11/ofdm_sync_long.h"
|
||||
#include "ieee802-11/ofdm_sync_short.h"
|
||||
#include "ieee802-11/wifi_signal_field.h"
|
||||
#include "ieee802-11/decode_mac.h"
|
||||
#include "ieee802-11/decode_signal.h"
|
||||
#include "ieee802-11/equalize_symbols.h"
|
||||
#include "ieee802-11/mac.h"
|
||||
#include "ieee802-11/mapper.h"
|
||||
#include "ieee802-11/parse_mac.h"
|
||||
#include "ieee802-11/sync_long.h"
|
||||
#include "ieee802-11/sync_short.h"
|
||||
#include "ieee802-11/signal_field.h"
|
||||
%}
|
||||
|
||||
%include "gnuradio/digital/packet_header_default.h"
|
||||
@@ -45,31 +45,31 @@
|
||||
%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_signal.h"
|
||||
%include "ieee802-11/ofdm_equalize_symbols.h"
|
||||
%include "ieee802-11/ofdm_mac.h"
|
||||
%include "ieee802-11/ofdm_mapper.h"
|
||||
%include "ieee802-11/ofdm_parse_mac.h"
|
||||
%include "ieee802-11/ofdm_sync_long.h"
|
||||
%include "ieee802-11/ofdm_sync_short.h"
|
||||
%include "ieee802-11/wifi_signal_field.h"
|
||||
%include "ieee802-11/decode_mac.h"
|
||||
%include "ieee802-11/decode_signal.h"
|
||||
%include "ieee802-11/equalize_symbols.h"
|
||||
%include "ieee802-11/mac.h"
|
||||
%include "ieee802-11/mapper.h"
|
||||
%include "ieee802-11/parse_mac.h"
|
||||
%include "ieee802-11/sync_long.h"
|
||||
%include "ieee802-11/sync_short.h"
|
||||
%include "ieee802-11/signal_field.h"
|
||||
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, chunks_to_symbols);
|
||||
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_signal);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_equalize_symbols);
|
||||
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_sync_long);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, ofdm_sync_short);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, decode_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, decode_signal);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, equalize_symbols);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, mapper);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, parse_mac);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, sync_long);
|
||||
GR_SWIG_BLOCK_MAGIC2(ieee802_11, sync_short);
|
||||
|
||||
%template(wifi_signal_field_sptr) boost::shared_ptr<gr::ieee802_11::wifi_signal_field>;
|
||||
%template(signal_field_sptr) boost::shared_ptr<gr::ieee802_11::signal_field>;
|
||||
%pythoncode %{
|
||||
wifi_signal_field_sptr.__repr__ = lambda self: "<wifi_signal_field>"
|
||||
wifi_signal_field = wifi_signal_field .make;
|
||||
signal_field_sptr.__repr__ = lambda self: "<signal_field>"
|
||||
signal_field = signal_field .make;
|
||||
%}
|
||||
|
||||
Reference in New Issue
Block a user