clang format, similar to GNU Radio

This commit is contained in:
Bastian Bloessl
2021-07-17 10:07:21 +02:00
parent 5f7e102e3d
commit a2491b5474
50 changed files with 3331 additions and 3059 deletions
+104
View File
@@ -0,0 +1,104 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 90
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^"(gnuradio)/'
Priority: 1
- Regex: '^<(gnuradio)/'
Priority: 2
- Regex: '^<(boost)/'
Priority: 98
- Regex: '^<[a-z]*>$'
Priority: 99
- Regex: '^".*"$'
Priority: 0
- Regex: '.*'
Priority: 10
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
+2 -2
View File
@@ -20,9 +20,9 @@
#include <gnuradio/attributes.h> #include <gnuradio/attributes.h>
#ifdef gnuradio_ieee802_11_EXPORTS #ifdef gnuradio_ieee802_11_EXPORTS
# define IEEE802_11_API __GR_ATTR_EXPORT #define IEEE802_11_API __GR_ATTR_EXPORT
#else #else
# define IEEE802_11_API __GR_ATTR_IMPORT #define IEEE802_11_API __GR_ATTR_IMPORT
#endif #endif
#endif /* INCLUDED_IEEE802_11_API_H */ #endif /* INCLUDED_IEEE802_11_API_H */
+1 -1
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_H #ifndef INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_H
#define INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_H #define INCLUDED_IEEE802_11_CHUNKS_TO_SYMBOLS_H
#include <ieee802_11/api.h>
#include <gnuradio/tagged_stream_block.h> #include <gnuradio/tagged_stream_block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
+1 -2
View File
@@ -18,8 +18,8 @@
#ifndef INCLUDED_IEEE802_11_CONSTELLATIONS_H #ifndef INCLUDED_IEEE802_11_CONSTELLATIONS_H
#define INCLUDED_IEEE802_11_CONSTELLATIONS_H #define INCLUDED_IEEE802_11_CONSTELLATIONS_H
#include <ieee802_11/api.h>
#include <gnuradio/digital/constellation.h> #include <gnuradio/digital/constellation.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -68,4 +68,3 @@ protected:
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_CONSTELLATIONS_H */ #endif /* INCLUDED_IEEE802_11_CONSTELLATIONS_H */
+1 -5
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_DECODE_MAC_H #ifndef INCLUDED_IEEE802_11_DECODE_MAC_H
#define INCLUDED_IEEE802_11_DECODE_MAC_H #define INCLUDED_IEEE802_11_DECODE_MAC_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -26,15 +26,11 @@ namespace ieee802_11 {
class IEEE802_11_API decode_mac : virtual public block class IEEE802_11_API decode_mac : virtual public block
{ {
public: public:
typedef boost::shared_ptr<decode_mac> sptr; typedef boost::shared_ptr<decode_mac> sptr;
static sptr make(bool log = false, bool debug = false); static sptr make(bool log = false, bool debug = false);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_DECODE_MAC_H */ #endif /* INCLUDED_IEEE802_11_DECODE_MAC_H */
+1 -3
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_ETHER_ENCAP_H #ifndef INCLUDED_IEEE802_11_ETHER_ENCAP_H
#define INCLUDED_IEEE802_11_ETHER_ENCAP_H #define INCLUDED_IEEE802_11_ETHER_ENCAP_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -26,10 +26,8 @@ namespace ieee802_11 {
class IEEE802_11_API ether_encap : virtual public block class IEEE802_11_API ether_encap : virtual public block
{ {
public: public:
typedef boost::shared_ptr<ether_encap> sptr; typedef boost::shared_ptr<ether_encap> sptr;
static sptr make(bool debug); static sptr make(bool debug);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+3 -2
View File
@@ -21,13 +21,14 @@
#ifndef INCLUDED_IEEE802_11_EXTRACT_CSI_H #ifndef INCLUDED_IEEE802_11_EXTRACT_CSI_H
#define INCLUDED_IEEE802_11_EXTRACT_CSI_H #define INCLUDED_IEEE802_11_EXTRACT_CSI_H
#include <ieee802_11/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class IEEE802_11_API extract_csi : virtual public gr::sync_block { class IEEE802_11_API extract_csi : virtual public gr::sync_block
{
public: public:
typedef boost::shared_ptr<extract_csi> sptr; typedef boost::shared_ptr<extract_csi> sptr;
static sptr make(); static sptr make();
+2 -3
View File
@@ -20,8 +20,8 @@
#ifndef INCLUDED_IEEE802_11_FRAME_EQUALIZER_H #ifndef INCLUDED_IEEE802_11_FRAME_EQUALIZER_H
#define INCLUDED_IEEE802_11_FRAME_EQUALIZER_H #define INCLUDED_IEEE802_11_FRAME_EQUALIZER_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
enum Equalizer { enum Equalizer {
LS = 0, LS = 0,
@@ -38,8 +38,7 @@ class IEEE802_11_API frame_equalizer : virtual public gr::block
public: public:
typedef boost::shared_ptr<frame_equalizer> sptr; typedef boost::shared_ptr<frame_equalizer> sptr;
static sptr make(Equalizer algo, double freq, double bw, static sptr make(Equalizer algo, double freq, double bw, bool log, bool debug);
bool log, bool debug);
virtual void set_algorithm(Equalizer algo) = 0; virtual void set_algorithm(Equalizer algo) = 0;
virtual void set_bandwidth(double bw) = 0; virtual void set_bandwidth(double bw) = 0;
virtual void set_frequency(double freq) = 0; virtual void set_frequency(double freq) = 0;
+1 -2
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_MAC_H #ifndef INCLUDED_IEEE802_11_MAC_H
#define INCLUDED_IEEE802_11_MAC_H #define INCLUDED_IEEE802_11_MAC_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -26,7 +26,6 @@ namespace ieee802_11 {
class IEEE802_11_API mac : virtual public block class IEEE802_11_API mac : virtual public block
{ {
public: public:
typedef boost::shared_ptr<mac> sptr; typedef boost::shared_ptr<mac> sptr;
static sptr make(std::vector<uint8_t> src_mac, static sptr make(std::vector<uint8_t> src_mac,
std::vector<uint8_t> dst_mac, std::vector<uint8_t> dst_mac,
+1 -2
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_MAPPER_H #ifndef INCLUDED_IEEE802_11_MAPPER_H
#define INCLUDED_IEEE802_11_MAPPER_H #define INCLUDED_IEEE802_11_MAPPER_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
enum Encoding { enum Encoding {
BPSK_1_2 = 0, BPSK_1_2 = 0,
@@ -37,7 +37,6 @@ namespace ieee802_11 {
class IEEE802_11_API mapper : virtual public block class IEEE802_11_API mapper : virtual public block
{ {
public: public:
typedef boost::shared_ptr<mapper> sptr; typedef boost::shared_ptr<mapper> sptr;
static sptr make(Encoding mcs, bool debug = false); static sptr make(Encoding mcs, bool debug = false);
virtual void set_encoding(Encoding mcs) = 0; virtual void set_encoding(Encoding mcs) = 0;
+1 -3
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_PARSE_MAC_H #ifndef INCLUDED_IEEE802_11_PARSE_MAC_H
#define INCLUDED_IEEE802_11_PARSE_MAC_H #define INCLUDED_IEEE802_11_PARSE_MAC_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -26,10 +26,8 @@ namespace ieee802_11 {
class IEEE802_11_API parse_mac : virtual public block class IEEE802_11_API parse_mac : virtual public block
{ {
public: public:
typedef boost::shared_ptr<parse_mac> sptr; typedef boost::shared_ptr<parse_mac> sptr;
static sptr make(bool log = false, bool debug = false); static sptr make(bool log = false, bool debug = false);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+1 -2
View File
@@ -18,8 +18,8 @@
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_H #ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_H
#define 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> #include <gnuradio/digital/packet_header_default.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -38,4 +38,3 @@ protected:
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_H */ #endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_H */
+2 -5
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_SYNC_LONG_H #ifndef INCLUDED_IEEE802_11_SYNC_LONG_H
#define INCLUDED_IEEE802_11_SYNC_LONG_H #define INCLUDED_IEEE802_11_SYNC_LONG_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -26,11 +26,8 @@ namespace ieee802_11 {
class IEEE802_11_API sync_long : virtual public block class IEEE802_11_API sync_long : virtual public block
{ {
public: public:
typedef boost::shared_ptr<sync_long> sptr; typedef boost::shared_ptr<sync_long> sptr;
static sptr make(unsigned int sync_length, static sptr make(unsigned int sync_length, bool log = false, bool debug = false);
bool log = false, bool debug = false);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+5 -4
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_SYNC_SHORT_H #ifndef INCLUDED_IEEE802_11_SYNC_SHORT_H
#define INCLUDED_IEEE802_11_SYNC_SHORT_H #define INCLUDED_IEEE802_11_SYNC_SHORT_H
#include <ieee802_11/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <ieee802_11/api.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -26,10 +26,11 @@ namespace ieee802_11 {
class IEEE802_11_API sync_short : virtual public block class IEEE802_11_API sync_short : virtual public block
{ {
public: public:
typedef boost::shared_ptr<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); static sptr make(double threshold,
unsigned int min_plateau,
bool log = false,
bool debug = false);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+18 -18
View File
@@ -22,16 +22,17 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
chunks_to_symbols::sptr chunks_to_symbols::sptr chunks_to_symbols::make()
chunks_to_symbols::make()
{ {
return gnuradio::get_initial_sptr(new chunks_to_symbols_impl()); return gnuradio::get_initial_sptr(new chunks_to_symbols_impl());
} }
chunks_to_symbols_impl::chunks_to_symbols_impl() : chunks_to_symbols_impl::chunks_to_symbols_impl()
tagged_stream_block("chunks_to_symbols", : tagged_stream_block("chunks_to_symbols",
io_signature::make(1, 1, sizeof(char)), io_signature::make(1, 1, sizeof(char)),
io_signature::make(1, 1, sizeof(gr_complex)), "packet_len") { io_signature::make(1, 1, sizeof(gr_complex)),
"packet_len")
{
d_bpsk = constellation_bpsk::make(); d_bpsk = constellation_bpsk::make();
d_qpsk = constellation_qpsk::make(); d_qpsk = constellation_qpsk::make();
@@ -41,23 +42,22 @@ chunks_to_symbols_impl::chunks_to_symbols_impl() :
d_mapping = d_bpsk; d_mapping = d_bpsk;
} }
chunks_to_symbols_impl::~chunks_to_symbols_impl() { } chunks_to_symbols_impl::~chunks_to_symbols_impl() {}
int int chunks_to_symbols_impl::work(int noutput_items,
chunks_to_symbols_impl::work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_int &ninput_items, gr_vector_const_void_star& input_items,
gr_vector_const_void_star &input_items, gr_vector_void_star& output_items)
gr_vector_void_star &output_items) { {
const unsigned char *in = (unsigned char*)input_items[0]; const unsigned char* in = (unsigned char*)input_items[0];
gr_complex *out = (gr_complex*)output_items[0]; gr_complex* out = (gr_complex*)output_items[0];
std::vector<tag_t> tags; std::vector<tag_t> tags;
get_tags_in_range(tags, 0, nitems_read(0), get_tags_in_range(
nitems_read(0) + ninput_items[0], tags, 0, nitems_read(0), nitems_read(0) + ninput_items[0], pmt::mp("encoding"));
pmt::mp("encoding")); if (tags.size() != 1) {
if(tags.size() != 1) {
throw std::runtime_error("no encoding in input stream"); throw std::runtime_error("no encoding in input stream");
} }
@@ -89,7 +89,7 @@ chunks_to_symbols_impl::work(int noutput_items,
break; break;
} }
for(int i = 0; i < ninput_items[0]; i++) { for (int i = 0; i < ninput_items[0]; i++) {
d_mapping->map_to_points(in[i], out + i); d_mapping->map_to_points(in[i], out + i);
} }
+3 -3
View File
@@ -30,9 +30,9 @@ public:
~chunks_to_symbols_impl(); ~chunks_to_symbols_impl();
int work(int noutput_items, int work(int noutput_items,
gr_vector_int &ninput_itmes, gr_vector_int& ninput_itmes,
gr_vector_const_void_star &input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star &output_items); gr_vector_void_star& output_items);
private: private:
boost::shared_ptr<gr::digital::constellation> d_mapping; boost::shared_ptr<gr::digital::constellation> d_mapping;
+116 -118
View File
@@ -18,14 +18,15 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
constellation_bpsk::sptr constellation_bpsk::sptr constellation_bpsk::make()
constellation_bpsk::make() { {
return constellation_bpsk::sptr(new constellation_bpsk_impl()); return constellation_bpsk::sptr(new constellation_bpsk_impl());
} }
constellation_bpsk::constellation_bpsk() {} constellation_bpsk::constellation_bpsk() {}
constellation_bpsk_impl::constellation_bpsk_impl() { constellation_bpsk_impl::constellation_bpsk_impl()
{
d_constellation.resize(2); d_constellation.resize(2);
d_constellation[0] = gr_complex(-1, 0); d_constellation[0] = gr_complex(-1, 0);
d_constellation[1] = gr_complex(1, 0); d_constellation[1] = gr_complex(1, 0);
@@ -34,51 +35,50 @@ constellation_bpsk_impl::constellation_bpsk_impl() {
calc_arity(); calc_arity();
} }
constellation_bpsk_impl::~constellation_bpsk_impl() { constellation_bpsk_impl::~constellation_bpsk_impl() {}
}
unsigned int unsigned int constellation_bpsk_impl::decision_maker(const gr_complex* sample)
constellation_bpsk_impl::decision_maker(const gr_complex *sample) { {
return (real(*sample) > 0); return (real(*sample) > 0);
} }
/**********************************************************/ /**********************************************************/
constellation_qpsk::sptr constellation_qpsk::sptr constellation_qpsk::make()
constellation_qpsk::make() { {
return constellation_qpsk::sptr(new constellation_qpsk_impl()); return constellation_qpsk::sptr(new constellation_qpsk_impl());
} }
constellation_qpsk::constellation_qpsk() {} constellation_qpsk::constellation_qpsk() {}
constellation_qpsk_impl::constellation_qpsk_impl() { constellation_qpsk_impl::constellation_qpsk_impl()
{
const float level = sqrt(float(0.5)); const float level = sqrt(float(0.5));
d_constellation.resize(4); d_constellation.resize(4);
// Gray-coded // Gray-coded
d_constellation[0] = gr_complex(-level, -level); d_constellation[0] = gr_complex(-level, -level);
d_constellation[1] = gr_complex( level, -level); d_constellation[1] = gr_complex(level, -level);
d_constellation[2] = gr_complex(-level, level); d_constellation[2] = gr_complex(-level, level);
d_constellation[3] = gr_complex( level, level); d_constellation[3] = gr_complex(level, level);
d_rotational_symmetry = 4; d_rotational_symmetry = 4;
d_dimensionality = 1; d_dimensionality = 1;
calc_arity(); calc_arity();
} }
constellation_qpsk_impl::~constellation_qpsk_impl() { constellation_qpsk_impl::~constellation_qpsk_impl() {}
}
unsigned int unsigned int constellation_qpsk_impl::decision_maker(const gr_complex* sample)
constellation_qpsk_impl::decision_maker(const gr_complex *sample) { {
return 2*(imag(*sample)>0) + (real(*sample)>0); return 2 * (imag(*sample) > 0) + (real(*sample) > 0);
} }
/**********************************************************/ /**********************************************************/
constellation_16qam::sptr constellation_16qam::sptr constellation_16qam::make()
constellation_16qam::make() { {
return constellation_16qam::sptr(new constellation_16qam_impl()); return constellation_16qam::sptr(new constellation_16qam_impl());
} }
@@ -89,33 +89,31 @@ constellation_16qam_impl::constellation_16qam_impl()
const float level = sqrt(float(0.1)); const float level = sqrt(float(0.1));
d_constellation.resize(16); d_constellation.resize(16);
d_constellation[ 0] = gr_complex(-3*level,-3*level); d_constellation[0] = gr_complex(-3 * level, -3 * level);
d_constellation[ 1] = gr_complex( 3*level,-3*level); d_constellation[1] = gr_complex(3 * level, -3 * level);
d_constellation[ 2] = gr_complex(-1*level,-3*level); d_constellation[2] = gr_complex(-1 * level, -3 * level);
d_constellation[ 3] = gr_complex( 1*level,-3*level); d_constellation[3] = gr_complex(1 * level, -3 * level);
d_constellation[ 4] = gr_complex(-3*level, 3*level); d_constellation[4] = gr_complex(-3 * level, 3 * level);
d_constellation[ 5] = gr_complex( 3*level, 3*level); d_constellation[5] = gr_complex(3 * level, 3 * level);
d_constellation[ 6] = gr_complex(-1*level, 3*level); d_constellation[6] = gr_complex(-1 * level, 3 * level);
d_constellation[ 7] = gr_complex( 1*level, 3*level); d_constellation[7] = gr_complex(1 * level, 3 * level);
d_constellation[ 8] = gr_complex(-3*level,-1*level); d_constellation[8] = gr_complex(-3 * level, -1 * level);
d_constellation[ 9] = gr_complex( 3*level,-1*level); d_constellation[9] = gr_complex(3 * level, -1 * level);
d_constellation[10] = gr_complex(-1*level,-1*level); d_constellation[10] = gr_complex(-1 * level, -1 * level);
d_constellation[11] = gr_complex( 1*level,-1*level); d_constellation[11] = gr_complex(1 * level, -1 * level);
d_constellation[12] = gr_complex(-3*level, 1*level); d_constellation[12] = gr_complex(-3 * level, 1 * level);
d_constellation[13] = gr_complex( 3*level, 1*level); d_constellation[13] = gr_complex(3 * level, 1 * level);
d_constellation[14] = gr_complex(-1*level, 1*level); d_constellation[14] = gr_complex(-1 * level, 1 * level);
d_constellation[15] = gr_complex( 1*level, 1*level); d_constellation[15] = gr_complex(1 * level, 1 * level);
d_rotational_symmetry = 4; d_rotational_symmetry = 4;
d_dimensionality = 1; d_dimensionality = 1;
calc_arity(); calc_arity();
} }
constellation_16qam_impl::~constellation_16qam_impl() { constellation_16qam_impl::~constellation_16qam_impl() {}
}
unsigned int unsigned int constellation_16qam_impl::decision_maker(const gr_complex* sample)
constellation_16qam_impl::decision_maker(const gr_complex *sample)
{ {
unsigned int ret = 0; unsigned int ret = 0;
const float level = sqrt(float(0.1)); const float level = sqrt(float(0.1));
@@ -123,9 +121,9 @@ constellation_16qam_impl::decision_maker(const gr_complex *sample)
float im = sample->imag(); float im = sample->imag();
ret |= re > 0; ret |= re > 0;
ret |= (std::abs(re) < (2*level)) << 1; ret |= (std::abs(re) < (2 * level)) << 1;
ret |= (im > 0) << 2; ret |= (im > 0) << 2;
ret |= (std::abs(im) < (2*level)) << 3; ret |= (std::abs(im) < (2 * level)) << 3;
return ret; return ret;
} }
@@ -133,103 +131,103 @@ constellation_16qam_impl::decision_maker(const gr_complex *sample)
/**********************************************************/ /**********************************************************/
constellation_64qam::sptr constellation_64qam::sptr constellation_64qam::make()
constellation_64qam::make() { {
return constellation_64qam::sptr(new constellation_64qam_impl()); return constellation_64qam::sptr(new constellation_64qam_impl());
} }
constellation_64qam::constellation_64qam() {} constellation_64qam::constellation_64qam() {}
constellation_64qam_impl::constellation_64qam_impl() { constellation_64qam_impl::constellation_64qam_impl()
const float level = sqrt(float(1/42.0)); {
const float level = sqrt(float(1 / 42.0));
d_constellation.resize(64); d_constellation.resize(64);
d_constellation[ 0] = gr_complex(-7*level,-7*level); d_constellation[0] = gr_complex(-7 * level, -7 * level);
d_constellation[ 1] = gr_complex( 7*level,-7*level); d_constellation[1] = gr_complex(7 * level, -7 * level);
d_constellation[ 2] = gr_complex(-1*level,-7*level); d_constellation[2] = gr_complex(-1 * level, -7 * level);
d_constellation[ 3] = gr_complex( 1*level,-7*level); d_constellation[3] = gr_complex(1 * level, -7 * level);
d_constellation[ 4] = gr_complex(-5*level,-7*level); d_constellation[4] = gr_complex(-5 * level, -7 * level);
d_constellation[ 5] = gr_complex( 5*level,-7*level); d_constellation[5] = gr_complex(5 * level, -7 * level);
d_constellation[ 6] = gr_complex(-3*level,-7*level); d_constellation[6] = gr_complex(-3 * level, -7 * level);
d_constellation[ 7] = gr_complex( 3*level,-7*level); d_constellation[7] = gr_complex(3 * level, -7 * level);
d_constellation[ 8] = gr_complex(-7*level, 7*level); d_constellation[8] = gr_complex(-7 * level, 7 * level);
d_constellation[ 9] = gr_complex( 7*level, 7*level); d_constellation[9] = gr_complex(7 * level, 7 * level);
d_constellation[10] = gr_complex(-1*level, 7*level); d_constellation[10] = gr_complex(-1 * level, 7 * level);
d_constellation[11] = gr_complex( 1*level, 7*level); d_constellation[11] = gr_complex(1 * level, 7 * level);
d_constellation[12] = gr_complex(-5*level, 7*level); d_constellation[12] = gr_complex(-5 * level, 7 * level);
d_constellation[13] = gr_complex( 5*level, 7*level); d_constellation[13] = gr_complex(5 * level, 7 * level);
d_constellation[14] = gr_complex(-3*level, 7*level); d_constellation[14] = gr_complex(-3 * level, 7 * level);
d_constellation[15] = gr_complex( 3*level, 7*level); d_constellation[15] = gr_complex(3 * level, 7 * level);
d_constellation[16] = gr_complex(-7*level,-1*level); d_constellation[16] = gr_complex(-7 * level, -1 * level);
d_constellation[17] = gr_complex( 7*level,-1*level); d_constellation[17] = gr_complex(7 * level, -1 * level);
d_constellation[18] = gr_complex(-1*level,-1*level); d_constellation[18] = gr_complex(-1 * level, -1 * level);
d_constellation[19] = gr_complex( 1*level,-1*level); d_constellation[19] = gr_complex(1 * level, -1 * level);
d_constellation[20] = gr_complex(-5*level,-1*level); d_constellation[20] = gr_complex(-5 * level, -1 * level);
d_constellation[21] = gr_complex( 5*level,-1*level); d_constellation[21] = gr_complex(5 * level, -1 * level);
d_constellation[22] = gr_complex(-3*level,-1*level); d_constellation[22] = gr_complex(-3 * level, -1 * level);
d_constellation[23] = gr_complex( 3*level,-1*level); d_constellation[23] = gr_complex(3 * level, -1 * level);
d_constellation[24] = gr_complex(-7*level, 1*level); d_constellation[24] = gr_complex(-7 * level, 1 * level);
d_constellation[25] = gr_complex( 7*level, 1*level); d_constellation[25] = gr_complex(7 * level, 1 * level);
d_constellation[26] = gr_complex(-1*level, 1*level); d_constellation[26] = gr_complex(-1 * level, 1 * level);
d_constellation[27] = gr_complex( 1*level, 1*level); d_constellation[27] = gr_complex(1 * level, 1 * level);
d_constellation[28] = gr_complex(-5*level, 1*level); d_constellation[28] = gr_complex(-5 * level, 1 * level);
d_constellation[29] = gr_complex( 5*level, 1*level); d_constellation[29] = gr_complex(5 * level, 1 * level);
d_constellation[30] = gr_complex(-3*level, 1*level); d_constellation[30] = gr_complex(-3 * level, 1 * level);
d_constellation[31] = gr_complex( 3*level, 1*level); d_constellation[31] = gr_complex(3 * level, 1 * level);
d_constellation[32] = gr_complex(-7*level,-5*level); d_constellation[32] = gr_complex(-7 * level, -5 * level);
d_constellation[33] = gr_complex( 7*level,-5*level); d_constellation[33] = gr_complex(7 * level, -5 * level);
d_constellation[34] = gr_complex(-1*level,-5*level); d_constellation[34] = gr_complex(-1 * level, -5 * level);
d_constellation[35] = gr_complex( 1*level,-5*level); d_constellation[35] = gr_complex(1 * level, -5 * level);
d_constellation[36] = gr_complex(-5*level,-5*level); d_constellation[36] = gr_complex(-5 * level, -5 * level);
d_constellation[37] = gr_complex( 5*level,-5*level); d_constellation[37] = gr_complex(5 * level, -5 * level);
d_constellation[38] = gr_complex(-3*level,-5*level); d_constellation[38] = gr_complex(-3 * level, -5 * level);
d_constellation[39] = gr_complex( 3*level,-5*level); d_constellation[39] = gr_complex(3 * level, -5 * level);
d_constellation[40] = gr_complex(-7*level, 5*level); d_constellation[40] = gr_complex(-7 * level, 5 * level);
d_constellation[41] = gr_complex( 7*level, 5*level); d_constellation[41] = gr_complex(7 * level, 5 * level);
d_constellation[42] = gr_complex(-1*level, 5*level); d_constellation[42] = gr_complex(-1 * level, 5 * level);
d_constellation[43] = gr_complex( 1*level, 5*level); d_constellation[43] = gr_complex(1 * level, 5 * level);
d_constellation[44] = gr_complex(-5*level, 5*level); d_constellation[44] = gr_complex(-5 * level, 5 * level);
d_constellation[45] = gr_complex( 5*level, 5*level); d_constellation[45] = gr_complex(5 * level, 5 * level);
d_constellation[46] = gr_complex(-3*level, 5*level); d_constellation[46] = gr_complex(-3 * level, 5 * level);
d_constellation[47] = gr_complex( 3*level, 5*level); d_constellation[47] = gr_complex(3 * level, 5 * level);
d_constellation[48] = gr_complex(-7*level,-3*level); d_constellation[48] = gr_complex(-7 * level, -3 * level);
d_constellation[49] = gr_complex( 7*level,-3*level); d_constellation[49] = gr_complex(7 * level, -3 * level);
d_constellation[50] = gr_complex(-1*level,-3*level); d_constellation[50] = gr_complex(-1 * level, -3 * level);
d_constellation[51] = gr_complex( 1*level,-3*level); d_constellation[51] = gr_complex(1 * level, -3 * level);
d_constellation[52] = gr_complex(-5*level,-3*level); d_constellation[52] = gr_complex(-5 * level, -3 * level);
d_constellation[53] = gr_complex( 5*level,-3*level); d_constellation[53] = gr_complex(5 * level, -3 * level);
d_constellation[54] = gr_complex(-3*level,-3*level); d_constellation[54] = gr_complex(-3 * level, -3 * level);
d_constellation[55] = gr_complex( 3*level,-3*level); d_constellation[55] = gr_complex(3 * level, -3 * level);
d_constellation[56] = gr_complex(-7*level, 3*level); d_constellation[56] = gr_complex(-7 * level, 3 * level);
d_constellation[57] = gr_complex( 7*level, 3*level); d_constellation[57] = gr_complex(7 * level, 3 * level);
d_constellation[58] = gr_complex(-1*level, 3*level); d_constellation[58] = gr_complex(-1 * level, 3 * level);
d_constellation[59] = gr_complex( 1*level, 3*level); d_constellation[59] = gr_complex(1 * level, 3 * level);
d_constellation[60] = gr_complex(-5*level, 3*level); d_constellation[60] = gr_complex(-5 * level, 3 * level);
d_constellation[61] = gr_complex( 5*level, 3*level); d_constellation[61] = gr_complex(5 * level, 3 * level);
d_constellation[62] = gr_complex(-3*level, 3*level); d_constellation[62] = gr_complex(-3 * level, 3 * level);
d_constellation[63] = gr_complex( 3*level, 3*level); d_constellation[63] = gr_complex(3 * level, 3 * level);
d_rotational_symmetry = 4; d_rotational_symmetry = 4;
d_dimensionality = 1; d_dimensionality = 1;
calc_arity(); calc_arity();
} }
constellation_64qam_impl::~constellation_64qam_impl() { constellation_64qam_impl::~constellation_64qam_impl() {}
}
unsigned int unsigned int constellation_64qam_impl::decision_maker(const gr_complex* sample)
constellation_64qam_impl::decision_maker(const gr_complex *sample) { {
unsigned int ret = 0; unsigned int ret = 0;
const float level = sqrt(float(1/42.0)); const float level = sqrt(float(1 / 42.0));
float re = sample->real(); float re = sample->real();
float im = sample->imag(); float im = sample->imag();
ret |= re > 0; ret |= re > 0;
ret |= (std::abs(re) < (4*level)) << 1; ret |= (std::abs(re) < (4 * level)) << 1;
ret |= (std::abs(re) < (6*level) && std::abs(re) > (2*level)) << 2; ret |= (std::abs(re) < (6 * level) && std::abs(re) > (2 * level)) << 2;
ret |= (im > 0) << 3; ret |= (im > 0) << 3;
ret |= (std::abs(im) < (4*level)) << 4; ret |= (std::abs(im) < (4 * level)) << 4;
ret |= (std::abs(im) < (6*level) && std::abs(im) > (2*level)) << 5; ret |= (std::abs(im) < (6 * level) && std::abs(im) > (2 * level)) << 5;
return ret; return ret;
} }
+4 -7
View File
@@ -28,7 +28,7 @@ public:
constellation_bpsk_impl(); constellation_bpsk_impl();
~constellation_bpsk_impl(); ~constellation_bpsk_impl();
unsigned int decision_maker(const gr_complex *sample); unsigned int decision_maker(const gr_complex* sample);
}; };
@@ -38,30 +38,27 @@ public:
constellation_qpsk_impl(); constellation_qpsk_impl();
~constellation_qpsk_impl(); ~constellation_qpsk_impl();
unsigned int decision_maker(const gr_complex *sample); unsigned int decision_maker(const gr_complex* sample);
}; };
class constellation_16qam_impl : public constellation_16qam class constellation_16qam_impl : public constellation_16qam
{ {
public: public:
constellation_16qam_impl(); constellation_16qam_impl();
~constellation_16qam_impl(); ~constellation_16qam_impl();
unsigned int decision_maker(const gr_complex *sample); unsigned int decision_maker(const gr_complex* sample);
}; };
class constellation_64qam_impl : public constellation_64qam class constellation_64qam_impl : public constellation_64qam
{ {
public: public:
constellation_64qam_impl(); constellation_64qam_impl();
~constellation_64qam_impl(); ~constellation_64qam_impl();
unsigned int decision_maker(const gr_complex *sample); unsigned int decision_maker(const gr_complex* sample);
}; };
+85 -64
View File
@@ -19,18 +19,19 @@
#include "utils.h" #include "utils.h"
#include "viterbi_decoder/viterbi_decoder.h" #include "viterbi_decoder/viterbi_decoder.h"
#include <boost/crc.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <boost/crc.hpp>
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
#define LINKTYPE_IEEE802_11 105 /* http://www.tcpdump.org/linktypes.html */ #define LINKTYPE_IEEE802_11 105 /* http://www.tcpdump.org/linktypes.html */
class decode_mac_impl : public decode_mac { class decode_mac_impl : public decode_mac
{
public: public:
decode_mac_impl(bool log, bool debug) : decode_mac_impl(bool log, bool debug)
block("decode_mac", : block("decode_mac",
gr::io_signature::make(1, 1, 48), gr::io_signature::make(1, 1, 48),
gr::io_signature::make(0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_log(log), d_log(log),
@@ -40,16 +41,19 @@ decode_mac_impl(bool log, bool debug) :
d_freq_offset(0.0), d_freq_offset(0.0),
d_ofdm(BPSK_1_2), d_ofdm(BPSK_1_2),
d_frame(d_ofdm, 0), d_frame(d_ofdm, 0),
d_frame_complete(true) { d_frame_complete(true)
{
message_port_register_out(pmt::mp("out")); message_port_register_out(pmt::mp("out"));
} }
int general_work (int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items,
gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) { gr_vector_void_star& output_items)
{
const uint8_t *in = (const uint8_t*)input_items[0]; const uint8_t* in = (const uint8_t*)input_items[0];
int i = 0; int i = 0;
@@ -58,48 +62,59 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
dout << "Decode MAC: input " << ninput_items[0] << std::endl; dout << "Decode MAC: input " << ninput_items[0] << std::endl;
while(i < ninput_items[0]) { while (i < ninput_items[0]) {
get_tags_in_range(tags, 0, nread + i, nread + i + 1, get_tags_in_range(
pmt::string_to_symbol("wifi_start")); tags, 0, nread + i, nread + i + 1, pmt::string_to_symbol("wifi_start"));
if(tags.size()) { if (tags.size()) {
if (d_frame_complete == false) { if (d_frame_complete == false) {
dout << "Warning: starting to receive new frame before old frame was complete" << std::endl; dout << "Warning: starting to receive new frame before old frame was "
dout << "Already copied " << copied << " out of " << d_frame.n_sym << " symbols of last frame" << std::endl; "complete"
<< std::endl;
dout << "Already copied " << copied << " out of " << d_frame.n_sym
<< " symbols of last frame" << std::endl;
} }
d_frame_complete = false; d_frame_complete = false;
pmt::pmt_t dict = tags[0].value; pmt::pmt_t dict = tags[0].value;
int len_data = pmt::to_uint64(pmt::dict_ref(dict, pmt::mp("frame_bytes"), pmt::from_uint64(MAX_PSDU_SIZE+1))); int len_data = pmt::to_uint64(pmt::dict_ref(
int encoding = pmt::to_uint64(pmt::dict_ref(dict, pmt::mp("encoding"), pmt::from_uint64(0))); dict, pmt::mp("frame_bytes"), pmt::from_uint64(MAX_PSDU_SIZE + 1)));
d_snr = pmt::to_double(pmt::dict_ref(dict, pmt::mp("snr"), pmt::from_double(0))); int encoding = pmt::to_uint64(
d_nom_freq = pmt::to_double(pmt::dict_ref(dict, pmt::mp("freq"), pmt::from_double(0))); pmt::dict_ref(dict, pmt::mp("encoding"), pmt::from_uint64(0)));
d_freq_offset = pmt::to_double(pmt::dict_ref(dict, pmt::mp("freq_offset"), pmt::from_double(0))); d_snr = pmt::to_double(
d_beta = pmt::to_double(pmt::dict_ref(dict, pmt::mp("beta"), pmt::from_double(0))); pmt::dict_ref(dict, pmt::mp("snr"), pmt::from_double(0)));
d_csi = pmt::c32vector_elements(pmt::dict_ref(dict, pmt::mp("csi"), pmt::make_c32vector(52, 0))); d_nom_freq = pmt::to_double(
pmt::dict_ref(dict, pmt::mp("freq"), pmt::from_double(0)));
d_freq_offset = pmt::to_double(
pmt::dict_ref(dict, pmt::mp("freq_offset"), pmt::from_double(0)));
d_beta = pmt::to_double(
pmt::dict_ref(dict, pmt::mp("beta"), pmt::from_double(0)));
d_csi = pmt::c32vector_elements(
pmt::dict_ref(dict, pmt::mp("csi"), pmt::make_c32vector(52, 0)));
ofdm_param ofdm = ofdm_param((Encoding)encoding); ofdm_param ofdm = ofdm_param((Encoding)encoding);
frame_param frame = frame_param(ofdm, len_data); frame_param frame = frame_param(ofdm, len_data);
// check for maximum frame size // check for maximum frame size
if(frame.n_sym <= MAX_SYM && frame.psdu_size <= MAX_PSDU_SIZE) { if (frame.n_sym <= MAX_SYM && frame.psdu_size <= MAX_PSDU_SIZE) {
d_ofdm = ofdm; d_ofdm = ofdm;
d_frame = frame; d_frame = frame;
copied = 0; copied = 0;
dout << "Decode MAC: frame start -- len " << len_data dout << "Decode MAC: frame start -- len " << len_data << " symbols "
<< " symbols " << frame.n_sym << " encoding " << frame.n_sym << " encoding " << encoding << std::endl;
<< encoding << std::endl;
} else { } else {
dout << "Dropping frame which is too large (symbols or bits)" << std::endl; dout << "Dropping frame which is too large (symbols or bits)"
<< std::endl;
} }
} }
if(copied < d_frame.n_sym) { if (copied < d_frame.n_sym) {
dout << "copy one symbol, copied " << copied << " out of " << d_frame.n_sym << std::endl; dout << "copy one symbol, copied " << copied << " out of "
<< d_frame.n_sym << std::endl;
std::memcpy(d_rx_symbols + (copied * 48), in, 48); std::memcpy(d_rx_symbols + (copied * 48), in, 48);
copied++; copied++;
if(copied == d_frame.n_sym) { if (copied == d_frame.n_sym) {
dout << "received complete frame - decoding" << std::endl; dout << "received complete frame - decoding" << std::endl;
decode(); decode();
in += 48; in += 48;
@@ -116,31 +131,32 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
consume(0, i); consume(0, i);
return 0; return 0;
} }
void decode() { void decode()
{
for(int i = 0; i < d_frame.n_sym * 48; i++) { for (int i = 0; i < d_frame.n_sym * 48; i++) {
for(int k = 0; k < d_ofdm.n_bpsc; k++) { for (int k = 0; k < d_ofdm.n_bpsc; k++) {
d_rx_bits[i*d_ofdm.n_bpsc + k] = !!(d_rx_symbols[i] & (1 << k)); d_rx_bits[i * d_ofdm.n_bpsc + k] = !!(d_rx_symbols[i] & (1 << k));
} }
} }
deinterleave(); deinterleave();
uint8_t *decoded = d_decoder.decode(&d_ofdm, &d_frame, d_deinterleaved_bits); uint8_t* decoded = d_decoder.decode(&d_ofdm, &d_frame, d_deinterleaved_bits);
descramble(decoded); descramble(decoded);
print_output(); print_output();
// skip service field // skip service field
boost::crc_32_type result; boost::crc_32_type result;
result.process_bytes(out_bytes + 2, d_frame.psdu_size); result.process_bytes(out_bytes + 2, d_frame.psdu_size);
if(result.checksum() != 558161692) { if (result.checksum() != 558161692) {
dout << "checksum wrong -- dropping" << std::endl; dout << "checksum wrong -- dropping" << std::endl;
return; return;
} }
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%") mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%") %
% d_ofdm.encoding % d_frame.psdu_size % d_frame.n_sym); d_ofdm.encoding % d_frame.psdu_size % d_frame.n_sym);
// create PDU // create PDU
pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_frame.psdu_size - 4); pmt::pmt_t blob = pmt::make_blob(out_bytes + 2, d_frame.psdu_size - 4);
@@ -154,39 +170,42 @@ void decode() {
dict = pmt::dict_add(dict, pmt::mp("csi"), pmt::init_c32vector(52, d_csi)); dict = pmt::dict_add(dict, pmt::mp("csi"), pmt::init_c32vector(52, d_csi));
dict = pmt::dict_add(dict, pmt::mp("dlt"), pmt::from_long(LINKTYPE_IEEE802_11)); dict = pmt::dict_add(dict, pmt::mp("dlt"), pmt::from_long(LINKTYPE_IEEE802_11));
message_port_pub(pmt::mp("out"), pmt::cons(dict, blob)); message_port_pub(pmt::mp("out"), pmt::cons(dict, blob));
} }
void deinterleave() { void deinterleave()
{
int n_cbps = d_ofdm.n_cbps; int n_cbps = d_ofdm.n_cbps;
int first[n_cbps]; int first[n_cbps];
int second[n_cbps]; int second[n_cbps];
int s = std::max(d_ofdm.n_bpsc / 2, 1); int s = std::max(d_ofdm.n_bpsc / 2, 1);
for(int j = 0; j < n_cbps; j++) { for (int j = 0; j < n_cbps; j++) {
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s); first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
} }
for(int i = 0; i < n_cbps; i++) { for (int i = 0; i < n_cbps; i++) {
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps)); second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
} }
int count = 0; int count = 0;
for(int i = 0; i < d_frame.n_sym; i++) { for (int i = 0; i < d_frame.n_sym; i++) {
for(int k = 0; k < n_cbps; k++) { for (int k = 0; k < n_cbps; k++) {
d_deinterleaved_bits[i * n_cbps + second[first[k]]] = d_rx_bits[i * n_cbps + k]; d_deinterleaved_bits[i * n_cbps + second[first[k]]] =
d_rx_bits[i * n_cbps + k];
}
} }
} }
}
void descramble (uint8_t *decoded_bits) { void descramble(uint8_t* decoded_bits)
{
int state = 0; int state = 0;
std::memset(out_bytes, 0, d_frame.psdu_size+2); std::memset(out_bytes, 0, d_frame.psdu_size + 2);
for(int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
if(decoded_bits[i]) { if (decoded_bits[i]) {
state |= 1 << (6 - i); state |= 1 << (6 - i);
} }
} }
@@ -195,34 +214,36 @@ void descramble (uint8_t *decoded_bits) {
int feedback; int feedback;
int bit; int bit;
for(int i = 7; i < d_frame.psdu_size*8+16; i++) { for (int i = 7; i < d_frame.psdu_size * 8 + 16; i++) {
feedback = ((!!(state & 64))) ^ (!!(state & 8)); feedback = ((!!(state & 64))) ^ (!!(state & 8));
bit = feedback ^ (decoded_bits[i] & 0x1); bit = feedback ^ (decoded_bits[i] & 0x1);
out_bytes[i/8] |= bit << (i%8); out_bytes[i / 8] |= bit << (i % 8);
state = ((state << 1) & 0x7e) | feedback; state = ((state << 1) & 0x7e) | feedback;
} }
} }
void print_output() { void print_output()
{
dout << std::endl; dout << std::endl;
dout << "psdu size" << d_frame.psdu_size << std::endl; dout << "psdu size" << d_frame.psdu_size << std::endl;
for(int i = 2; i < d_frame.psdu_size+2; i++) { for (int i = 2; i < d_frame.psdu_size + 2; i++) {
dout << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " "; dout << std::setfill('0') << std::setw(2) << std::hex
if(i % 16 == 15) { << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " ";
if (i % 16 == 15) {
dout << std::endl; dout << std::endl;
} }
} }
dout << std::endl; dout << std::endl;
for(int i = 2; i < d_frame.psdu_size+2; i++) { for (int i = 2; i < d_frame.psdu_size + 2; i++) {
if((out_bytes[i] > 31) && (out_bytes[i] < 127)) { if ((out_bytes[i] > 31) && (out_bytes[i] < 127)) {
dout << ((char) out_bytes[i]); dout << ((char)out_bytes[i]);
} else { } else {
dout << "."; dout << ".";
} }
} }
dout << std::endl; dout << std::endl;
} }
private: private:
bool d_debug; bool d_debug;
@@ -246,7 +267,7 @@ private:
bool d_frame_complete; bool d_frame_complete;
}; };
decode_mac::sptr decode_mac::sptr decode_mac::make(bool log, bool debug)
decode_mac::make(bool log, bool debug) { {
return gnuradio::get_initial_sptr(new decode_mac_impl(log, debug)); return gnuradio::get_initial_sptr(new decode_mac_impl(log, debug));
} }
+14 -18
View File
@@ -21,27 +21,23 @@
using namespace gr::ieee802_11::equalizer; using namespace gr::ieee802_11::equalizer;
const gr_complex base::LONG[] = { const gr_complex base::LONG[] = { 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 1, 1, -1,
0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1,
1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 0, 1, -1, -1, 1, 1, -1,
1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1,
1, 1, 0, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
-1, 1, -1, -1, -1, -1, -1, 1, 1, -1,
-1, 1, -1, 1, -1, 1, 1, 1, 1, 0,
0, 0, 0, 0
};
const gr_complex base::POLARITY[127] = { const gr_complex base::POLARITY[127] = {
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1,
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1,
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1,
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1,
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1,
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1, };
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
std::vector<gr_complex> base::get_csi() { std::vector<gr_complex> base::get_csi()
{
std::vector<gr_complex> csi; std::vector<gr_complex> csi;
csi.reserve(52); csi.reserve(52);
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
+10 -5
View File
@@ -18,17 +18,22 @@
#ifndef INCLUDED_IEEE802_11_EQUALIZER_BASE_H #ifndef INCLUDED_IEEE802_11_EQUALIZER_BASE_H
#define INCLUDED_IEEE802_11_EQUALIZER_BASE_H #define INCLUDED_IEEE802_11_EQUALIZER_BASE_H
#include <gnuradio/gr_complex.h>
#include <gnuradio/digital/constellation.h> #include <gnuradio/digital/constellation.h>
#include <gnuradio/gr_complex.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
namespace equalizer { namespace equalizer {
class base { class base
{
public: public:
virtual ~base() {}; virtual ~base(){};
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) = 0; virtual void equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod) = 0;
virtual double get_snr() = 0; virtual double get_snr() = 0;
static const gr_complex POLARITY[127]; static const gr_complex POLARITY[127];
@@ -41,7 +46,7 @@ protected:
gr_complex d_H[64]; gr_complex d_H[64];
}; };
} /* namespace channel_estimation */ } // namespace equalizer
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
+27 -20
View File
@@ -19,11 +19,16 @@
using namespace gr::ieee802_11::equalizer; using namespace gr::ieee802_11::equalizer;
void comb::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) { void comb::equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod)
{
gr_complex pilot[4]; gr_complex pilot[4];
if(n < 2) { if (n < 2) {
pilot[0] = in[11]; pilot[0] = in[11];
pilot[1] = -in[25]; pilot[1] = -in[25];
pilot[2] = in[39]; pilot[2] = in[39];
@@ -38,30 +43,35 @@ void comb::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, b
gr_complex avg = (pilot[0] + pilot[1] + pilot[2] + pilot[3]) / gr_complex(4, 0); gr_complex avg = (pilot[0] + pilot[1] + pilot[2] + pilot[3]) / gr_complex(4, 0);
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
gr_complex H; gr_complex H;
if(i <= 11) { if (i <= 11) {
H = gr_complex((11-i) / 11.0, 0) * avg + gr_complex( i / 11.0, 0) * pilot[0]; H = gr_complex((11 - i) / 11.0, 0) * avg + gr_complex(i / 11.0, 0) * pilot[0];
} else if(i <= 25) { } else if (i <= 25) {
H = gr_complex((25-i) / 14.0, 0) * pilot[0] + gr_complex((i-11) / 14.0, 0) * pilot[1]; H = gr_complex((25 - i) / 14.0, 0) * pilot[0] +
} else if(i <= 39) { gr_complex((i - 11) / 14.0, 0) * pilot[1];
H = gr_complex((39-i) / 14.0, 0) * pilot[1] + gr_complex((i-25) / 14.0, 0) * pilot[2]; } else if (i <= 39) {
} else if(i <= 53) { H = gr_complex((39 - i) / 14.0, 0) * pilot[1] +
H = gr_complex((53-i) / 14.0, 0) * pilot[2] + gr_complex((i-39) / 14.0, 0) * pilot[3]; gr_complex((i - 25) / 14.0, 0) * pilot[2];
} else if (i <= 53) {
H = gr_complex((53 - i) / 14.0, 0) * pilot[2] +
gr_complex((i - 39) / 14.0, 0) * pilot[3];
} else { } else {
H = gr_complex((64-i) / 11.0, 0) * pilot[3] + gr_complex((i-53) / 11.0, 0) * avg; H = gr_complex((64 - i) / 11.0, 0) * pilot[3] +
gr_complex((i - 53) / 11.0, 0) * avg;
} }
if(n == 0) { if (n == 0) {
d_H[i] = H; d_H[i] = H;
} else { } else {
d_H[i] = gr_complex(1-alpha, 0) * d_H[i] + gr_complex(alpha, 0) * H; d_H[i] = gr_complex(1 - alpha, 0) * d_H[i] + gr_complex(alpha, 0) * H;
} }
} }
int c = 0; int c = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) { if ((i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) ||
(i > 58)) {
continue; continue;
} else { } else {
symbols[c] = in[i] / d_H[i]; symbols[c] = in[i] / d_H[i];
@@ -71,7 +81,4 @@ void comb::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, b
} }
} }
double double comb::get_snr() { return 42; }
comb::get_snr() {
return 42;
}
+8 -4
View File
@@ -24,18 +24,22 @@ namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
namespace equalizer { namespace equalizer {
class comb: public base { class comb : public base
{
public: public:
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod); virtual void equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod);
double get_snr(); double get_snr();
private: private:
const double alpha = 0.2; const double alpha = 0.2;
}; };
} /* namespace channel_estimation */ } // namespace equalizer
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
#endif /* INCLUDED_IEEE802_11_EQUALIZER_COMB_H */ #endif /* INCLUDED_IEEE802_11_EQUALIZER_COMB_H */
+16 -12
View File
@@ -21,16 +21,21 @@
using namespace gr::ieee802_11::equalizer; using namespace gr::ieee802_11::equalizer;
void lms::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) { void lms::equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod)
{
if(n == 0) { if (n == 0) {
std::memcpy(d_H, in, 64 * sizeof(gr_complex)); std::memcpy(d_H, in, 64 * sizeof(gr_complex));
} else if(n == 1) { } else if (n == 1) {
double signal = 0; double signal = 0;
double noise = 0; double noise = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if((i == 32) || (i < 6) || ( i > 58)) { if ((i == 32) || (i < 6) || (i > 58)) {
continue; continue;
} }
noise += std::pow(std::abs(d_H[i] - in[i]), 2); noise += std::pow(std::abs(d_H[i] - in[i]), 2);
@@ -43,22 +48,21 @@ void lms::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, bo
} else { } else {
int c = 0; int c = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) { if ((i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) ||
(i < 6) || (i > 58)) {
continue; continue;
} else { } else {
symbols[c] = in[i] / d_H[i]; symbols[c] = in[i] / d_H[i];
bits[c] = mod->decision_maker(&symbols[c]); bits[c] = mod->decision_maker(&symbols[c]);
gr_complex point; gr_complex point;
mod->map_to_points(bits[c], &point); mod->map_to_points(bits[c], &point);
d_H[i] = gr_complex(1-alpha,0) * d_H[i] + gr_complex(alpha,0) * in[i] / point; d_H[i] = gr_complex(1 - alpha, 0) * d_H[i] +
gr_complex(alpha, 0) * in[i] / point;
c++; c++;
} }
} }
} }
} }
double double lms::get_snr() { return d_snr; }
lms::get_snr() {
return d_snr;
}
+9 -3
View File
@@ -25,9 +25,15 @@ namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
namespace equalizer { namespace equalizer {
class lms: public base { class lms : public base
{
public: public:
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod); virtual void equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod);
private: private:
double get_snr(); double get_snr();
@@ -35,7 +41,7 @@ private:
const double alpha = 0.5; const double alpha = 0.5;
}; };
} /* namespace channel_estimation */ } // namespace equalizer
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
+14 -10
View File
@@ -21,16 +21,21 @@
using namespace gr::ieee802_11::equalizer; using namespace gr::ieee802_11::equalizer;
void ls::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) { void ls::equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod)
{
if(n == 0) { if (n == 0) {
std::memcpy(d_H, in, 64 * sizeof(gr_complex)); std::memcpy(d_H, in, 64 * sizeof(gr_complex));
} else if(n == 1) { } else if (n == 1) {
double signal = 0; double signal = 0;
double noise = 0; double noise = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if((i == 32) || (i < 6) || ( i > 58)) { if ((i == 32) || (i < 6) || (i > 58)) {
continue; continue;
} }
noise += std::pow(std::abs(d_H[i] - in[i]), 2); noise += std::pow(std::abs(d_H[i] - in[i]), 2);
@@ -44,8 +49,9 @@ void ls::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boo
} else { } else {
int c = 0; int c = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) { if ((i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) ||
(i < 6) || (i > 58)) {
continue; continue;
} else { } else {
symbols[c] = in[i] / d_H[i]; symbols[c] = in[i] / d_H[i];
@@ -56,6 +62,4 @@ void ls::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boo
} }
} }
double ls::get_snr() { double ls::get_snr() { return d_snr; }
return d_snr;
}
+9 -4
View File
@@ -25,17 +25,22 @@ namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
namespace equalizer { namespace equalizer {
class ls: public base { class ls : public base
{
public: public:
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod); virtual void equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod);
virtual double get_snr(); virtual double get_snr();
private: private:
double d_snr; double d_snr;
}; };
} /* namespace channel_estimation */ } // namespace equalizer
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
#endif /* INCLUDED_IEEE802_11_EQUALIZER_LS_H */ #endif /* INCLUDED_IEEE802_11_EQUALIZER_LS_H */
+21 -17
View File
@@ -21,16 +21,21 @@
using namespace gr::ieee802_11::equalizer; using namespace gr::ieee802_11::equalizer;
void sta::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod) { void sta::equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod)
{
if(n == 0) { if (n == 0) {
std::memcpy(d_H, in, 64 * sizeof(gr_complex)); std::memcpy(d_H, in, 64 * sizeof(gr_complex));
} else if(n == 1) { } else if (n == 1) {
double signal = 0; double signal = 0;
double noise = 0; double noise = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if((i == 32) || (i < 6) || ( i > 58)) { if ((i == 32) || (i < 6) || (i > 58)) {
continue; continue;
} }
noise += std::pow(std::abs(d_H[i] - in[i]), 2); noise += std::pow(std::abs(d_H[i] - in[i]), 2);
@@ -54,8 +59,9 @@ void sta::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, bo
H[53] = in[53] * -p; H[53] = in[53] * -p;
int c = 0; int c = 0;
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) { if ((i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) ||
(i < 6) || (i > 58)) {
continue; continue;
} else { } else {
symbols[c] = in[i] / d_H[i]; symbols[c] = in[i] / d_H[i];
@@ -67,11 +73,11 @@ void sta::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, bo
} }
} }
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
int n = 0; int n = 0;
gr_complex s = 0; gr_complex s = 0;
for(int k = i-beta; k <= i+beta; k++) { for (int k = i - beta; k <= i + beta; k++) {
if((k == 32) || (k < 6) || ( k > 58)) { if ((k == 32) || (k < 6) || (k > 58)) {
continue; continue;
} }
n++; n++;
@@ -80,16 +86,14 @@ void sta::equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, bo
H_update[i] = s / gr_complex(n, 0); H_update[i] = s / gr_complex(n, 0);
} }
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
if((i < 6) || ( i > 58)) { if ((i < 6) || (i > 58)) {
continue; continue;
} }
d_H[i] = gr_complex(1-alpha,0) * d_H[i] + gr_complex(alpha,0) * H_update[i]; d_H[i] =
gr_complex(1 - alpha, 0) * d_H[i] + gr_complex(alpha, 0) * H_update[i];
} }
} }
} }
double double sta::get_snr() { return d_snr; }
sta::get_snr() {
return d_snr;
}
+8 -3
View File
@@ -25,9 +25,14 @@ namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
namespace equalizer { namespace equalizer {
class sta: public base { class sta : public base
{
public: public:
virtual void equalize(gr_complex *in, int n, gr_complex *symbols, uint8_t *bits, boost::shared_ptr<gr::digital::constellation> mod); virtual void equalize(gr_complex* in,
int n,
gr_complex* symbols,
uint8_t* bits,
boost::shared_ptr<gr::digital::constellation> mod);
double get_snr(); double get_snr();
private: private:
@@ -37,7 +42,7 @@ private:
const int beta = 2; const int beta = 2;
}; };
} /* namespace channel_estimation */ } // namespace equalizer
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
+31 -27
View File
@@ -17,37 +17,42 @@
#include "ether_encap_impl.h" #include "ether_encap_impl.h"
#include "utils.h" #include "utils.h"
#include <gnuradio/io_signature.h>
#include <gnuradio/block_detail.h> #include <gnuradio/block_detail.h>
#include <gnuradio/io_signature.h>
#include <string> #include <string>
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
ether_encap_impl::ether_encap_impl(bool debug) : ether_encap_impl::ether_encap_impl(bool debug)
block("ether_encap", : block("ether_encap",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_debug(debug), d_debug(debug),
d_last_seq(123) { d_last_seq(123)
{
message_port_register_out(pmt::mp("to tap")); message_port_register_out(pmt::mp("to tap"));
message_port_register_out(pmt::mp("to wifi")); message_port_register_out(pmt::mp("to wifi"));
message_port_register_in(pmt::mp("from tap")); message_port_register_in(pmt::mp("from tap"));
set_msg_handler(pmt::mp("from tap"), boost::bind(&ether_encap_impl::from_tap, this, boost::placeholders::_1)); set_msg_handler(
pmt::mp("from tap"),
boost::bind(&ether_encap_impl::from_tap, this, boost::placeholders::_1));
message_port_register_in(pmt::mp("from wifi")); message_port_register_in(pmt::mp("from wifi"));
set_msg_handler(pmt::mp("from wifi"), boost::bind(&ether_encap_impl::from_wifi, this, boost::placeholders::_1)); set_msg_handler(
pmt::mp("from wifi"),
boost::bind(&ether_encap_impl::from_wifi, this, boost::placeholders::_1));
} }
void void ether_encap_impl::from_wifi(pmt::pmt_t msg)
ether_encap_impl::from_wifi(pmt::pmt_t msg) { {
msg = pmt::cdr(msg); msg = pmt::cdr(msg);
int data_len = pmt::blob_length(msg); int data_len = pmt::blob_length(msg);
const mac_header *mhdr = reinterpret_cast<const mac_header*>(pmt::blob_data(msg)); const mac_header* mhdr = reinterpret_cast<const mac_header*>(pmt::blob_data(msg));
if(d_last_seq == mhdr->seq_nr) { if (d_last_seq == mhdr->seq_nr) {
dout << "Ether Encap: frame already seen -- skipping" << std::endl; dout << "Ether Encap: frame already seen -- skipping" << std::endl;
return; return;
} }
@@ -55,16 +60,16 @@ ether_encap_impl::from_wifi(pmt::pmt_t msg) {
d_last_seq = mhdr->seq_nr; d_last_seq = mhdr->seq_nr;
if(data_len < 33) { if (data_len < 33) {
dout << "Ether Encap: frame too short to parse (<33)" << std::endl; dout << "Ether Encap: frame too short to parse (<33)" << std::endl;
return; return;
} }
// this is more than needed // this is more than needed
char *buf = static_cast<char*>(std::malloc(data_len + sizeof(ethernet_header))); char* buf = static_cast<char*>(std::malloc(data_len + sizeof(ethernet_header)));
ethernet_header *ehdr = reinterpret_cast<ethernet_header*>(buf); ethernet_header* ehdr = reinterpret_cast<ethernet_header*>(buf);
if(((mhdr->frame_control >> 2) & 3) != 2) { if (((mhdr->frame_control >> 2) & 3) != 2) {
dout << "this is not a data frame -- ignoring" << std::endl; dout << "this is not a data frame -- ignoring" << std::endl;
return; return;
} }
@@ -73,16 +78,16 @@ ether_encap_impl::from_wifi(pmt::pmt_t msg) {
std::memcpy(ehdr->src, mhdr->addr2, 6); std::memcpy(ehdr->src, mhdr->addr2, 6);
ehdr->type = 0x0008; ehdr->type = 0x0008;
char *frame = (char*)pmt::blob_data(msg); char* frame = (char*)pmt::blob_data(msg);
// DATA // DATA
if((((mhdr->frame_control) >> 2) & 63) == 2) { if ((((mhdr->frame_control) >> 2) & 63) == 2) {
memcpy(buf + sizeof(ethernet_header), frame + 32, data_len - 32); memcpy(buf + sizeof(ethernet_header), frame + 32, data_len - 32);
pmt::pmt_t payload = pmt::make_blob(buf, data_len - 32 + 14); pmt::pmt_t payload = pmt::make_blob(buf, data_len - 32 + 14);
message_port_pub(pmt::mp("to tap"), pmt::cons(pmt::PMT_NIL, payload)); message_port_pub(pmt::mp("to tap"), pmt::cons(pmt::PMT_NIL, payload));
// QoS Data // QoS Data
} else if((((mhdr->frame_control) >> 2) & 63) == 34) { } else if ((((mhdr->frame_control) >> 2) & 63) == 34) {
memcpy(buf + sizeof(ethernet_header), frame + 34, data_len - 34); memcpy(buf + sizeof(ethernet_header), frame + 34, data_len - 34);
pmt::pmt_t payload = pmt::make_blob(buf, data_len - 34 + 14); pmt::pmt_t payload = pmt::make_blob(buf, data_len - 34 + 14);
@@ -92,18 +97,18 @@ ether_encap_impl::from_wifi(pmt::pmt_t msg) {
free(buf); free(buf);
} }
void void ether_encap_impl::from_tap(pmt::pmt_t msg)
ether_encap_impl::from_tap(pmt::pmt_t msg) { {
size_t len = pmt::blob_length(pmt::cdr(msg)); size_t len = pmt::blob_length(pmt::cdr(msg));
const char* data = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg))); const char* data = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
const ethernet_header *ehdr = reinterpret_cast<const ethernet_header*>(data); const ethernet_header* ehdr = reinterpret_cast<const ethernet_header*>(data);
switch(ehdr->type) { switch (ehdr->type) {
case 0x0008: { case 0x0008: {
std::cout << "ether type: IP" << std::endl; std::cout << "ether type: IP" << std::endl;
char *buf = static_cast<char*>(malloc(len + 8 - sizeof(ethernet_header))); char* buf = static_cast<char*>(malloc(len + 8 - sizeof(ethernet_header)));
buf[0] = 0xaa; buf[0] = 0xaa;
buf[1] = 0xaa; buf[1] = 0xaa;
buf[2] = 0x03; buf[2] = 0x03;
@@ -112,7 +117,8 @@ ether_encap_impl::from_tap(pmt::pmt_t msg) {
buf[5] = 0x00; buf[5] = 0x00;
buf[6] = 0x08; buf[6] = 0x08;
buf[7] = 0x00; buf[7] = 0x00;
std::memcpy(buf + 8, data + sizeof(ethernet_header), len - sizeof(ethernet_header)); std::memcpy(
buf + 8, data + sizeof(ethernet_header), len - sizeof(ethernet_header));
pmt::pmt_t blob = pmt::make_blob(buf, len + 8 - sizeof(ethernet_header)); pmt::pmt_t blob = pmt::make_blob(buf, len + 8 - sizeof(ethernet_header));
message_port_pub(pmt::mp("to wifi"), pmt::cons(pmt::PMT_NIL, blob)); message_port_pub(pmt::mp("to wifi"), pmt::cons(pmt::PMT_NIL, blob));
break; break;
@@ -124,11 +130,9 @@ ether_encap_impl::from_tap(pmt::pmt_t msg) {
std::cout << "unknown ether type" << std::endl; std::cout << "unknown ether type" << std::endl;
break; break;
} }
} }
ether_encap::sptr ether_encap::sptr ether_encap::make(bool debug)
ether_encap::make(bool debug) { {
return gnuradio::get_initial_sptr(new ether_encap_impl(debug)); return gnuradio::get_initial_sptr(new ether_encap_impl(debug));
} }
+7 -7
View File
@@ -22,27 +22,27 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
struct ethernet_header { struct ethernet_header {
uint8_t dest[6]; uint8_t dest[6];
uint8_t src[6]; uint8_t src[6];
uint16_t type; uint16_t type;
}__attribute__((packed)); } __attribute__((packed));
class ether_encap_impl : public ether_encap { class ether_encap_impl : public ether_encap
{
public: public:
ether_encap_impl(bool debug); ether_encap_impl(bool debug);
private: private:
void from_tap(pmt::pmt_t msg); void from_tap(pmt::pmt_t msg);
void from_wifi(pmt::pmt_t msg); void from_wifi(pmt::pmt_t msg);
bool d_debug; bool d_debug;
uint16_t d_last_seq; uint16_t d_last_seq;
}; };
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_ETHER_ENCAP_IMPL_H */ #endif /* INCLUDED_IEEE802_11_ETHER_ENCAP_IMPL_H */
+12 -9
View File
@@ -22,28 +22,32 @@
#include "config.h" #include "config.h"
#endif #endif
#include <gnuradio/io_signature.h>
#include "extract_csi_impl.h" #include "extract_csi_impl.h"
#include <gnuradio/io_signature.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
extract_csi::sptr extract_csi::make() { extract_csi::sptr extract_csi::make()
{
return gnuradio::get_initial_sptr(new extract_csi_impl()); return gnuradio::get_initial_sptr(new extract_csi_impl());
} }
extract_csi_impl::extract_csi_impl() extract_csi_impl::extract_csi_impl()
: gr::sync_block("extract_csi", gr::io_signature::make(0, 0, 0), : gr::sync_block("extract_csi",
gr::io_signature::make(1, 1, 52 * sizeof(gr_complex))) { gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 1, 52 * sizeof(gr_complex)))
{
message_port_register_in(pmt::mp("pdu in")); message_port_register_in(pmt::mp("pdu in"));
} }
extract_csi_impl::~extract_csi_impl() {} extract_csi_impl::~extract_csi_impl() {}
int extract_csi_impl::work(int noutput_items, int extract_csi_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star &output_items) { gr_vector_void_star& output_items)
{
pmt::pmt_t pdu(delete_head_nowait(pmt::mp("pdu in"))); pmt::pmt_t pdu(delete_head_nowait(pmt::mp("pdu in")));
if (pdu.get() == NULL) if (pdu.get() == NULL)
@@ -57,10 +61,9 @@ int extract_csi_impl::work(int noutput_items,
if (!pmt::dict_has_key(d_meta, pmt::mp("csi"))) if (!pmt::dict_has_key(d_meta, pmt::mp("csi")))
return 0; return 0;
d_csi = pmt::c32vector_elements( d_csi = pmt::c32vector_elements(pmt::dict_ref(d_meta, pmt::mp("csi"), pmt::PMT_NIL));
pmt::dict_ref(d_meta, pmt::mp("csi"), pmt::PMT_NIL));
gr_complex *out = (gr_complex *)output_items[0]; gr_complex* out = (gr_complex*)output_items[0];
std::copy(d_csi.begin(), d_csi.end(), out); std::copy(d_csi.begin(), d_csi.end(), out);
+5 -3
View File
@@ -26,7 +26,8 @@
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
class extract_csi_impl : public extract_csi { class extract_csi_impl : public extract_csi
{
private: private:
pmt::pmt_t d_meta; pmt::pmt_t d_meta;
std::vector<gr_complex> d_csi; std::vector<gr_complex> d_csi;
@@ -35,8 +36,9 @@ public:
extract_csi_impl(); extract_csi_impl();
~extract_csi_impl(); ~extract_csi_impl();
int work(int noutput_items, gr_vector_const_void_star &input_items, int work(int noutput_items,
gr_vector_void_star &output_items); gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+107 -95
View File
@@ -15,12 +15,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "frame_equalizer_impl.h"
#include "equalizer/base.h" #include "equalizer/base.h"
#include "equalizer/comb.h" #include "equalizer/comb.h"
#include "equalizer/lms.h" #include "equalizer/lms.h"
#include "equalizer/ls.h" #include "equalizer/ls.h"
#include "equalizer/sta.h" #include "equalizer/sta.h"
#include "frame_equalizer_impl.h"
#include "utils.h" #include "utils.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@@ -28,19 +28,28 @@ namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
frame_equalizer::sptr frame_equalizer::sptr
frame_equalizer::make(Equalizer algo, double freq, double bw, bool log, bool debug) { frame_equalizer::make(Equalizer algo, double freq, double bw, bool log, bool debug)
return gnuradio::get_initial_sptr {
(new frame_equalizer_impl(algo, freq, bw, log, debug)); return gnuradio::get_initial_sptr(
new frame_equalizer_impl(algo, freq, bw, log, debug));
} }
frame_equalizer_impl::frame_equalizer_impl(Equalizer algo, double freq, double bw, bool log, bool debug) : frame_equalizer_impl::frame_equalizer_impl(
gr::block("frame_equalizer", Equalizer algo, double freq, double bw, bool log, bool debug)
: gr::block("frame_equalizer",
gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)), gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)),
gr::io_signature::make(1, 1, 48)), gr::io_signature::make(1, 1, 48)),
d_current_symbol(0), d_log(log), d_debug(debug), d_equalizer(NULL), d_current_symbol(0),
d_freq(freq), d_bw(bw), d_frame_bytes(0), d_frame_symbols(0), d_log(log),
d_freq_offset_from_synclong(0.0) { d_debug(debug),
d_equalizer(NULL),
d_freq(freq),
d_bw(bw),
d_frame_bytes(0),
d_frame_symbols(0),
d_freq_offset_from_synclong(0.0)
{
message_port_register_out(pmt::mp("symbols")); message_port_register_out(pmt::mp("symbols"));
@@ -55,16 +64,15 @@ frame_equalizer_impl::frame_equalizer_impl(Equalizer algo, double freq, double b
set_algorithm(algo); set_algorithm(algo);
} }
frame_equalizer_impl::~frame_equalizer_impl() { frame_equalizer_impl::~frame_equalizer_impl() {}
}
void void frame_equalizer_impl::set_algorithm(Equalizer algo)
frame_equalizer_impl::set_algorithm(Equalizer algo) { {
gr::thread::scoped_lock lock(d_mutex); gr::thread::scoped_lock lock(d_mutex);
delete d_equalizer; delete d_equalizer;
switch(algo) { switch (algo) {
case COMB: case COMB:
dout << "Comb" << std::endl; dout << "Comb" << std::endl;
@@ -87,52 +95,55 @@ frame_equalizer_impl::set_algorithm(Equalizer algo) {
} }
} }
void void frame_equalizer_impl::set_bandwidth(double bw)
frame_equalizer_impl::set_bandwidth(double bw) { {
gr::thread::scoped_lock lock(d_mutex); gr::thread::scoped_lock lock(d_mutex);
d_bw = bw; d_bw = bw;
} }
void void frame_equalizer_impl::set_frequency(double freq)
frame_equalizer_impl::set_frequency(double freq) { {
gr::thread::scoped_lock lock(d_mutex); gr::thread::scoped_lock lock(d_mutex);
d_freq = freq; d_freq = freq;
} }
void void frame_equalizer_impl::forecast(int noutput_items,
frame_equalizer_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { gr_vector_int& ninput_items_required)
{
ninput_items_required[0] = noutput_items; ninput_items_required[0] = noutput_items;
} }
int int frame_equalizer_impl::general_work(int noutput_items,
frame_equalizer_impl::general_work (int noutput_items, gr_vector_int& ninput_items,
gr_vector_int &ninput_items, gr_vector_const_void_star& input_items,
gr_vector_const_void_star &input_items, gr_vector_void_star& output_items)
gr_vector_void_star &output_items) { {
gr::thread::scoped_lock lock(d_mutex); gr::thread::scoped_lock lock(d_mutex);
const gr_complex *in = (const gr_complex *) input_items[0]; const gr_complex* in = (const gr_complex*)input_items[0];
uint8_t *out = (uint8_t *) output_items[0]; uint8_t* out = (uint8_t*)output_items[0];
int i = 0; int i = 0;
int o = 0; int o = 0;
gr_complex symbols[48]; gr_complex symbols[48];
gr_complex current_symbol[64]; gr_complex current_symbol[64];
dout << "FRAME EQUALIZER: input " << ninput_items[0] << " output " << noutput_items << std::endl; dout << "FRAME EQUALIZER: input " << ninput_items[0] << " output " << noutput_items
<< std::endl;
while((i < ninput_items[0]) && (o < noutput_items)) { while ((i < ninput_items[0]) && (o < noutput_items)) {
get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("wifi_start")); get_tags_in_window(tags, 0, i, i + 1, pmt::string_to_symbol("wifi_start"));
// new frame // new frame
if(tags.size()) { if (tags.size()) {
d_current_symbol = 0; d_current_symbol = 0;
d_frame_symbols = 0; d_frame_symbols = 0;
d_frame_mod = d_bpsk; d_frame_mod = d_bpsk;
d_freq_offset_from_synclong = pmt::to_double(tags.front().value) * d_bw / (2 * M_PI); d_freq_offset_from_synclong =
pmt::to_double(tags.front().value) * d_bw / (2 * M_PI);
d_epsilon0 = pmt::to_double(tags.front().value) * d_bw / (2 * M_PI * d_freq); d_epsilon0 = pmt::to_double(tags.front().value) * d_bw / (2 * M_PI * d_freq);
d_er = 0; d_er = 0;
@@ -140,45 +151,40 @@ frame_equalizer_impl::general_work (int noutput_items,
} }
// not interesting -> skip // not interesting -> skip
if(d_current_symbol > (d_frame_symbols + 2)) { if (d_current_symbol > (d_frame_symbols + 2)) {
i++; i++;
continue; continue;
} }
std::memcpy(current_symbol, in + i*64, 64*sizeof(gr_complex)); std::memcpy(current_symbol, in + i * 64, 64 * sizeof(gr_complex));
// compensate sampling offset // compensate sampling offset
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
current_symbol[i] *= exp(gr_complex(0, 2*M_PI*d_current_symbol*80*(d_epsilon0 + d_er)*(i-32)/64)); current_symbol[i] *= exp(gr_complex(0,
2 * M_PI * d_current_symbol * 80 *
(d_epsilon0 + d_er) * (i - 32) / 64));
} }
gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127];
double beta; double beta;
if(d_current_symbol < 2) { if (d_current_symbol < 2) {
beta = arg( beta = arg(current_symbol[11] - current_symbol[25] + current_symbol[39] +
current_symbol[11] -
current_symbol[25] +
current_symbol[39] +
current_symbol[53]); current_symbol[53]);
} else { } else {
beta = arg( beta = arg((current_symbol[11] * p) + (current_symbol[39] * p) +
(current_symbol[11] * p) + (current_symbol[25] * p) + (current_symbol[53] * -p));
(current_symbol[39] * p) +
(current_symbol[25] * p) +
(current_symbol[53] * -p));
} }
double er = arg( double er = arg((conj(d_prev_pilots[0]) * current_symbol[11] * p) +
(conj(d_prev_pilots[0]) * current_symbol[11] * p) +
(conj(d_prev_pilots[1]) * current_symbol[25] * p) + (conj(d_prev_pilots[1]) * current_symbol[25] * p) +
(conj(d_prev_pilots[2]) * current_symbol[39] * p) + (conj(d_prev_pilots[2]) * current_symbol[39] * p) +
(conj(d_prev_pilots[3]) * current_symbol[53] * -p)); (conj(d_prev_pilots[3]) * current_symbol[53] * -p));
er *= d_bw / (2 * M_PI * d_freq * 80); er *= d_bw / (2 * M_PI * d_freq * 80);
if(d_current_symbol < 2) { if (d_current_symbol < 2) {
d_prev_pilots[0] = current_symbol[11]; d_prev_pilots[0] = current_symbol[11];
d_prev_pilots[1] = -current_symbol[25]; d_prev_pilots[1] = -current_symbol[25];
d_prev_pilots[2] = current_symbol[39]; d_prev_pilots[2] = current_symbol[39];
@@ -191,48 +197,57 @@ frame_equalizer_impl::general_work (int noutput_items,
} }
// compensate residual frequency offset // compensate residual frequency offset
for(int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
current_symbol[i] *= exp(gr_complex(0, -beta)); current_symbol[i] *= exp(gr_complex(0, -beta));
} }
// update estimate of residual frequency offset // update estimate of residual frequency offset
if(d_current_symbol >= 2) { if (d_current_symbol >= 2) {
double alpha = 0.1; double alpha = 0.1;
d_er = (1-alpha) * d_er + alpha * er; d_er = (1 - alpha) * d_er + alpha * er;
} }
// do equalization // do equalization
d_equalizer->equalize(current_symbol, d_current_symbol, d_equalizer->equalize(
symbols, out + o * 48, d_frame_mod); current_symbol, d_current_symbol, symbols, out + o * 48, d_frame_mod);
// signal field // signal field
if(d_current_symbol == 2) { if (d_current_symbol == 2) {
if(decode_signal_field(out + o * 48)) { if (decode_signal_field(out + o * 48)) {
pmt::pmt_t dict = pmt::make_dict(); pmt::pmt_t dict = pmt::make_dict();
dict = pmt::dict_add(dict, pmt::mp("frame_bytes"), pmt::from_uint64(d_frame_bytes)); dict = pmt::dict_add(
dict = pmt::dict_add(dict, pmt::mp("encoding"), pmt::from_uint64(d_frame_encoding)); dict, pmt::mp("frame_bytes"), pmt::from_uint64(d_frame_bytes));
dict = pmt::dict_add(dict, pmt::mp("snr"), pmt::from_double(d_equalizer->get_snr())); dict = pmt::dict_add(
dict, pmt::mp("encoding"), pmt::from_uint64(d_frame_encoding));
dict = pmt::dict_add(
dict, pmt::mp("snr"), pmt::from_double(d_equalizer->get_snr()));
dict = pmt::dict_add(dict, pmt::mp("freq"), pmt::from_double(d_freq)); dict = pmt::dict_add(dict, pmt::mp("freq"), pmt::from_double(d_freq));
dict = pmt::dict_add(dict, pmt::mp("freq_offset"), pmt::from_double(d_freq_offset_from_synclong)); dict = pmt::dict_add(dict,
pmt::mp("freq_offset"),
pmt::from_double(d_freq_offset_from_synclong));
dict = pmt::dict_add(dict, pmt::mp("beta"), pmt::from_double(beta)); dict = pmt::dict_add(dict, pmt::mp("beta"), pmt::from_double(beta));
std::vector<gr_complex> csi = d_equalizer->get_csi(); std::vector<gr_complex> csi = d_equalizer->get_csi();
dict = pmt::dict_add(dict, pmt::mp("csi"), pmt::init_c32vector(csi.size(), csi)); dict = pmt::dict_add(
dict, pmt::mp("csi"), pmt::init_c32vector(csi.size(), csi));
add_item_tag(0, nitems_written(0) + o, add_item_tag(0,
nitems_written(0) + o,
pmt::string_to_symbol("wifi_start"), pmt::string_to_symbol("wifi_start"),
dict, dict,
pmt::string_to_symbol(alias())); pmt::string_to_symbol(alias()));
} }
} }
if(d_current_symbol > 2) { if (d_current_symbol > 2) {
o++; o++;
pmt::pmt_t pdu = pmt::make_dict(); pmt::pmt_t pdu = pmt::make_dict();
message_port_pub(pmt::mp("symbols"), pmt::cons(pmt::make_dict(), pmt::init_c32vector(48, symbols))); message_port_pub(
pmt::mp("symbols"),
pmt::cons(pmt::make_dict(), pmt::init_c32vector(48, symbols)));
} }
i++; i++;
@@ -243,94 +258,94 @@ frame_equalizer_impl::general_work (int noutput_items,
return o; return o;
} }
bool bool frame_equalizer_impl::decode_signal_field(uint8_t* rx_bits)
frame_equalizer_impl::decode_signal_field(uint8_t *rx_bits) { {
static ofdm_param ofdm(BPSK_1_2); static ofdm_param ofdm(BPSK_1_2);
static frame_param frame(ofdm, 0); static frame_param frame(ofdm, 0);
deinterleave(rx_bits); deinterleave(rx_bits);
uint8_t *decoded_bits = d_decoder.decode(&ofdm, &frame, d_deinterleaved); uint8_t* decoded_bits = d_decoder.decode(&ofdm, &frame, d_deinterleaved);
return parse_signal(decoded_bits); return parse_signal(decoded_bits);
} }
void void frame_equalizer_impl::deinterleave(uint8_t* rx_bits)
frame_equalizer_impl::deinterleave(uint8_t *rx_bits) { {
for(int i = 0; i < 48; i++) { for (int i = 0; i < 48; i++) {
d_deinterleaved[i] = rx_bits[interleaver_pattern[i]]; d_deinterleaved[i] = rx_bits[interleaver_pattern[i]];
} }
} }
bool bool frame_equalizer_impl::parse_signal(uint8_t* decoded_bits)
frame_equalizer_impl::parse_signal(uint8_t *decoded_bits) { {
int r = 0; int r = 0;
d_frame_bytes = 0; d_frame_bytes = 0;
bool parity = false; bool parity = false;
for(int i = 0; i < 17; i++) { for (int i = 0; i < 17; i++) {
parity ^= decoded_bits[i]; parity ^= decoded_bits[i];
if((i < 4) && decoded_bits[i]) { if ((i < 4) && decoded_bits[i]) {
r = r | (1 << i); r = r | (1 << i);
} }
if(decoded_bits[i] && (i > 4) && (i < 17)) { if (decoded_bits[i] && (i > 4) && (i < 17)) {
d_frame_bytes = d_frame_bytes | (1 << (i-5)); d_frame_bytes = d_frame_bytes | (1 << (i - 5));
} }
} }
if(parity != decoded_bits[17]) { if (parity != decoded_bits[17]) {
dout << "SIGNAL: wrong parity" << std::endl; dout << "SIGNAL: wrong parity" << std::endl;
return false; return false;
} }
switch(r) { switch (r) {
case 11: case 11:
d_frame_encoding = 0; d_frame_encoding = 0;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 24); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)24);
d_frame_mod = d_bpsk; d_frame_mod = d_bpsk;
dout << "Encoding: 3 Mbit/s "; dout << "Encoding: 3 Mbit/s ";
break; break;
case 15: case 15:
d_frame_encoding = 1; d_frame_encoding = 1;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 36); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)36);
d_frame_mod = d_bpsk; d_frame_mod = d_bpsk;
dout << "Encoding: 4.5 Mbit/s "; dout << "Encoding: 4.5 Mbit/s ";
break; break;
case 10: case 10:
d_frame_encoding = 2; d_frame_encoding = 2;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 48); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)48);
d_frame_mod = d_qpsk; d_frame_mod = d_qpsk;
dout << "Encoding: 6 Mbit/s "; dout << "Encoding: 6 Mbit/s ";
break; break;
case 14: case 14:
d_frame_encoding = 3; d_frame_encoding = 3;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 72); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)72);
d_frame_mod = d_qpsk; d_frame_mod = d_qpsk;
dout << "Encoding: 9 Mbit/s "; dout << "Encoding: 9 Mbit/s ";
break; break;
case 9: case 9:
d_frame_encoding = 4; d_frame_encoding = 4;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 96); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)96);
d_frame_mod = d_16qam; d_frame_mod = d_16qam;
dout << "Encoding: 12 Mbit/s "; dout << "Encoding: 12 Mbit/s ";
break; break;
case 13: case 13:
d_frame_encoding = 5; d_frame_encoding = 5;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 144); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)144);
d_frame_mod = d_16qam; d_frame_mod = d_16qam;
dout << "Encoding: 18 Mbit/s "; dout << "Encoding: 18 Mbit/s ";
break; break;
case 8: case 8:
d_frame_encoding = 6; d_frame_encoding = 6;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 192); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)192);
d_frame_mod = d_64qam; d_frame_mod = d_64qam;
dout << "Encoding: 24 Mbit/s "; dout << "Encoding: 24 Mbit/s ";
break; break;
case 12: case 12:
d_frame_encoding = 7; d_frame_encoding = 7;
d_frame_symbols = (int) ceil((16 + 8 * d_frame_bytes + 6) / (double) 216); d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)216);
d_frame_mod = d_64qam; d_frame_mod = d_64qam;
dout << "Encoding: 27 Mbit/s "; dout << "Encoding: 27 Mbit/s ";
break; break;
@@ -339,19 +354,16 @@ frame_equalizer_impl::parse_signal(uint8_t *decoded_bits) {
return false; return false;
} }
mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%") mylog(boost::format("encoding: %1% - length: %2% - symbols: %3%") % d_frame_encoding %
% d_frame_encoding % d_frame_bytes % d_frame_symbols); d_frame_bytes % d_frame_symbols);
return true; return true;
} }
const int const int frame_equalizer_impl::interleaver_pattern[48] = {
frame_equalizer_impl::interleaver_pattern[48] = { 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45,
0, 3, 6, 9,12,15,18,21, 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46,
24,27,30,33,36,39,42,45, 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47
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};
} /* namespace ieee802_11 */ } /* namespace ieee802_11 */
} /* namespace gr */ } /* namespace gr */
+10 -12
View File
@@ -18,10 +18,10 @@
#ifndef INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H #ifndef INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H
#define INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H #define INCLUDED_IEEE802_11_FRAME_EQUALIZER_IMPL_H
#include <ieee802_11/frame_equalizer.h>
#include <ieee802_11/constellations.h>
#include "equalizer/base.h" #include "equalizer/base.h"
#include "viterbi_decoder/viterbi_decoder.h" #include "viterbi_decoder/viterbi_decoder.h"
#include <ieee802_11/constellations.h>
#include <ieee802_11/frame_equalizer.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -37,20 +37,18 @@ public:
void set_bandwidth(double bw); void set_bandwidth(double bw);
void set_frequency(double freq); void set_frequency(double freq);
void forecast (int noutput_items, gr_vector_int &ninput_items_required); void forecast(int noutput_items, gr_vector_int& ninput_items_required);
int general_work(int noutput_items, int general_work(int noutput_items,
gr_vector_int &ninput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star &output_items); gr_vector_void_star& output_items);
private: private:
bool parse_signal(uint8_t* signal);
bool decode_signal_field(uint8_t* rx_bits);
void deinterleave(uint8_t* rx_bits);
equalizer::base* d_equalizer;
bool parse_signal(uint8_t *signal);
bool decode_signal_field(uint8_t *rx_bits);
void deinterleave(uint8_t *rx_bits);
equalizer::base *d_equalizer;
gr::thread::mutex d_mutex; gr::thread::mutex d_mutex;
std::vector<gr::tag_t> tags; std::vector<gr::tag_t> tags;
bool d_debug; bool d_debug;
+51 -39
View File
@@ -16,8 +16,8 @@
*/ */
#include <ieee802_11/mac.h> #include <ieee802_11/mac.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/block_detail.h> #include <gnuradio/block_detail.h>
#include <gnuradio/io_signature.h>
#include "utils.h" #include "utils.h"
@@ -34,37 +34,44 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
class mac_impl : public mac { class mac_impl : public mac
{
public: public:
mac_impl(std::vector<uint8_t> src_mac,
mac_impl(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_mac) : std::vector<uint8_t> dst_mac,
block("mac", std::vector<uint8_t> bss_mac)
gr::io_signature::make(0, 0, 0), : block("mac", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)),
gr::io_signature::make(0, 0, 0)), d_seq_nr(0)
d_seq_nr(0) { {
message_port_register_out(pmt::mp("phy out")); message_port_register_out(pmt::mp("phy out"));
message_port_register_out(pmt::mp("app out")); message_port_register_out(pmt::mp("app out"));
message_port_register_in(pmt::mp("app in")); message_port_register_in(pmt::mp("app in"));
set_msg_handler(pmt::mp("app in"), boost::bind(&mac_impl::app_in, this, boost::placeholders::_1)); set_msg_handler(pmt::mp("app in"),
boost::bind(&mac_impl::app_in, this, boost::placeholders::_1));
message_port_register_in(pmt::mp("phy in")); message_port_register_in(pmt::mp("phy in"));
set_msg_handler(pmt::mp("phy in"), boost::bind(&mac_impl::phy_in, this, boost::placeholders::_1)); set_msg_handler(pmt::mp("phy in"),
boost::bind(&mac_impl::phy_in, this, boost::placeholders::_1));
if(!check_mac(src_mac)) throw std::invalid_argument("wrong mac address size"); if (!check_mac(src_mac))
if(!check_mac(dst_mac)) throw std::invalid_argument("wrong mac address size"); throw std::invalid_argument("wrong mac address size");
if(!check_mac(bss_mac)) throw std::invalid_argument("wrong mac address size"); if (!check_mac(dst_mac))
throw std::invalid_argument("wrong mac address size");
if (!check_mac(bss_mac))
throw std::invalid_argument("wrong mac address size");
for(int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
d_src_mac[i] = src_mac[i]; d_src_mac[i] = src_mac[i];
d_dst_mac[i] = dst_mac[i]; d_dst_mac[i] = dst_mac[i];
d_bss_mac[i] = bss_mac[i]; d_bss_mac[i] = bss_mac[i];
} }
} }
void phy_in (pmt::pmt_t msg) { void phy_in(pmt::pmt_t msg)
{
// this must be a pair // this must be a pair
if (!pmt::is_blob(pmt::cdr(msg))) { if (!pmt::is_blob(pmt::cdr(msg))) {
throw std::runtime_error("PMT must be blob"); throw std::runtime_error("PMT must be blob");
@@ -73,36 +80,37 @@ void phy_in (pmt::pmt_t msg) {
// strip MAC header // strip MAC header
// TODO: check for frame type to determine header size // TODO: check for frame type to determine header size
pmt::pmt_t blob(pmt::cdr(msg)); pmt::pmt_t blob(pmt::cdr(msg));
const char *mpdu = reinterpret_cast<const char *>(pmt::blob_data(blob)); 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); 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)); message_port_pub(pmt::mp("app out"), pmt::cons(pmt::car(msg), msdu));
} }
void app_in (pmt::pmt_t msg) { void app_in(pmt::pmt_t msg)
{
size_t msg_len; size_t msg_len;
const char *msdu; const char* msdu;
std::string str; std::string str;
if(pmt::is_symbol(msg)) { if (pmt::is_symbol(msg)) {
str = pmt::symbol_to_string(msg); str = pmt::symbol_to_string(msg);
msg_len = str.length(); msg_len = str.length();
msdu = str.data(); msdu = str.data();
} else if(pmt::is_pair(msg)) { } else if (pmt::is_pair(msg)) {
msg_len = pmt::blob_length(pmt::cdr(msg)); msg_len = pmt::blob_length(pmt::cdr(msg));
msdu = reinterpret_cast<const char *>(pmt::blob_data(pmt::cdr(msg))); msdu = reinterpret_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
} else { } else {
throw std::invalid_argument("MAC expects PDUs or strings"); throw std::invalid_argument("MAC expects PDUs or strings");
return; return;
} }
if(msg_len > MAX_PAYLOAD_SIZE) { if (msg_len > MAX_PAYLOAD_SIZE) {
throw std::invalid_argument("Frame too large (> 1500)"); throw std::invalid_argument("Frame too large (> 1500)");
} }
@@ -119,16 +127,17 @@ void app_in (pmt::pmt_t msg) {
// pdu // pdu
message_port_pub(pmt::mp("phy out"), pmt::cons(dict, mac)); message_port_pub(pmt::mp("phy out"), pmt::cons(dict, mac));
} }
void generate_mac_data_frame(const char *msdu, int msdu_size, int *psdu_size) { void generate_mac_data_frame(const char* msdu, int msdu_size, int* psdu_size)
{
// mac header // mac header
mac_header header; mac_header header;
header.frame_control = 0x0008; header.frame_control = 0x0008;
header.duration = 0x0000; header.duration = 0x0000;
for(int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
header.addr1[i] = d_dst_mac[i]; header.addr1[i] = d_dst_mac[i];
header.addr2[i] = d_src_mac[i]; header.addr2[i] = d_src_mac[i];
header.addr3[i] = d_bss_mac[i]; header.addr3[i] = d_bss_mac[i];
@@ -136,32 +145,34 @@ void generate_mac_data_frame(const char *msdu, int msdu_size, int *psdu_size) {
header.seq_nr = 0; header.seq_nr = 0;
for (int i = 0; i < 12; i++) { for (int i = 0; i < 12; i++) {
if(d_seq_nr & (1 << i)) { if (d_seq_nr & (1 << i)) {
header.seq_nr |= (1 << (i + 4)); header.seq_nr |= (1 << (i + 4));
} }
} }
header.seq_nr = htole16(header.seq_nr); header.seq_nr = htole16(header.seq_nr);
d_seq_nr++; d_seq_nr++;
//header size is 24, plus 4 for FCS means 28 bytes // header size is 24, plus 4 for FCS means 28 bytes
*psdu_size = 28 + msdu_size; *psdu_size = 28 + msdu_size;
//copy mac header into psdu // copy mac header into psdu
std::memcpy(d_psdu, &header, 24); std::memcpy(d_psdu, &header, 24);
//copy msdu into psdu // copy msdu into psdu
memcpy(d_psdu + 24, msdu, msdu_size); memcpy(d_psdu + 24, msdu, msdu_size);
//compute and store fcs // compute and store fcs
boost::crc_32_type result; boost::crc_32_type result;
result.process_bytes(d_psdu, msdu_size + 24); result.process_bytes(d_psdu, msdu_size + 24);
uint32_t fcs = result.checksum(); uint32_t fcs = result.checksum();
memcpy(d_psdu + msdu_size + 24, &fcs, sizeof(uint32_t)); memcpy(d_psdu + msdu_size + 24, &fcs, sizeof(uint32_t));
} }
bool check_mac(std::vector<uint8_t> mac) { bool check_mac(std::vector<uint8_t> mac)
if(mac.size() != 6) return false; {
if (mac.size() != 6)
return false;
return true; return true;
} }
private: private:
uint16_t d_seq_nr; uint16_t d_seq_nr;
@@ -171,8 +182,9 @@ private:
uint8_t d_psdu[MAX_PSDU_SIZE]; uint8_t d_psdu[MAX_PSDU_SIZE];
}; };
mac::sptr mac::sptr mac::make(std::vector<uint8_t> src_mac,
mac::make(std::vector<uint8_t> src_mac, std::vector<uint8_t> dst_mac, std::vector<uint8_t> bss_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)); return gnuradio::get_initial_sptr(new mac_impl(src_mac, dst_mac, bss_mac));
} }
+52 -46
View File
@@ -14,93 +14,99 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <ieee802_11/mapper.h>
#include "utils.h" #include "utils.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <ieee802_11/mapper.h>
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
class mapper_impl : public mapper { class mapper_impl : public mapper
{
public: public:
static const int DATA_CARRIERS = 48;
static const int DATA_CARRIERS = 48; mapper_impl(Encoding e, bool debug)
: block("mapper",
mapper_impl(Encoding e, bool debug) :
block ("mapper",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 1, sizeof(char))), gr::io_signature::make(1, 1, sizeof(char))),
d_symbols_offset(0), d_symbols_offset(0),
d_symbols(NULL), d_symbols(NULL),
d_debug(debug), d_debug(debug),
d_scrambler(1), d_scrambler(1),
d_ofdm(e) { d_ofdm(e)
{
message_port_register_in(pmt::mp("in")); message_port_register_in(pmt::mp("in"));
set_encoding(e); set_encoding(e);
} }
~mapper_impl() { ~mapper_impl() { free(d_symbols); }
free(d_symbols);
}
void print_message(const char *msg, size_t len) { void print_message(const char* msg, size_t len)
{
dout << std::hex << "MAPPER input symbols" << std::endl dout << std::hex << "MAPPER input symbols" << std::endl
<< "===========================" << std::endl; << "===========================" << std::endl;
for(int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
dout << std::hex << (int)msg[i] << " "; dout << std::hex << (int)msg[i] << " ";
} }
dout << std::dec << std::endl; dout << std::dec << std::endl;
} }
int general_work(int noutput, gr_vector_int& ninput_items, int general_work(int noutput,
gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items ) { gr_vector_void_star& output_items)
{
unsigned char *out = (unsigned char*)output_items[0]; unsigned char* out = (unsigned char*)output_items[0];
dout << "MAPPER called offset: " << d_symbols_offset << dout << "MAPPER called offset: " << d_symbols_offset
" length: " << d_symbols_len << std::endl; << " length: " << d_symbols_len << std::endl;
while(!d_symbols_offset) { while (!d_symbols_offset) {
pmt::pmt_t msg(delete_head_nowait(pmt::intern("in"))); pmt::pmt_t msg(delete_head_nowait(pmt::intern("in")));
if(!msg.get()) { if (!msg.get()) {
return 0; return 0;
} }
if(pmt::is_pair(msg)) { if (pmt::is_pair(msg)) {
dout << "MAPPER: received new message" << std::endl; dout << "MAPPER: received new message" << std::endl;
gr::thread::scoped_lock lock(d_mutex); gr::thread::scoped_lock lock(d_mutex);
int psdu_length = pmt::blob_length(pmt::cdr(msg)); int psdu_length = pmt::blob_length(pmt::cdr(msg));
const char *psdu = static_cast<const char*>(pmt::blob_data(pmt::cdr(msg))); const char* psdu =
static_cast<const char*>(pmt::blob_data(pmt::cdr(msg)));
// ############ INSERT MAC STUFF // ############ INSERT MAC STUFF
frame_param frame(d_ofdm, psdu_length); frame_param frame(d_ofdm, psdu_length);
if(frame.n_sym > MAX_SYM) { if (frame.n_sym > MAX_SYM) {
std::cout << "packet too large, maximum number of symbols is " << MAX_SYM << std::endl; std::cout << "packet too large, maximum number of symbols is "
<< MAX_SYM << std::endl;
return 0; return 0;
} }
//alloc memory for modulation steps // alloc memory for modulation steps
char *data_bits = (char*)calloc(frame.n_data_bits, sizeof(char)); char* data_bits = (char*)calloc(frame.n_data_bits, sizeof(char));
char *scrambled_data = (char*)calloc(frame.n_data_bits, sizeof(char)); char* scrambled_data = (char*)calloc(frame.n_data_bits, sizeof(char));
char *encoded_data = (char*)calloc(frame.n_data_bits * 2, sizeof(char)); char* encoded_data = (char*)calloc(frame.n_data_bits * 2, sizeof(char));
char *punctured_data = (char*)calloc(frame.n_encoded_bits, 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* interleaved_data =
char *symbols = (char*)calloc((frame.n_encoded_bits / d_ofdm.n_bpsc), sizeof(char)); (char*)calloc(frame.n_encoded_bits, sizeof(char));
char* symbols =
(char*)calloc((frame.n_encoded_bits / d_ofdm.n_bpsc), sizeof(char));
//generate the WIFI data field, adding service field and pad bits // generate the WIFI data field, adding service field and pad bits
generate_bits(psdu, data_bits, frame); generate_bits(psdu, data_bits, frame);
// scrambling // scrambling
scramble(data_bits, scrambled_data, frame, d_scrambler++); scramble(data_bits, scrambled_data, frame, d_scrambler++);
if(d_scrambler > 127) { if (d_scrambler > 127) {
d_scrambler = 1; d_scrambler = 1;
} }
@@ -110,10 +116,10 @@ int general_work(int noutput, gr_vector_int& ninput_items,
convolutional_encoding(scrambled_data, encoded_data, frame); convolutional_encoding(scrambled_data, encoded_data, frame);
// puncturing // puncturing
puncturing(encoded_data, punctured_data, frame, d_ofdm); puncturing(encoded_data, punctured_data, frame, d_ofdm);
//std::cout << "punctured" << std::endl; // std::cout << "punctured" << std::endl;
// interleaving // interleaving
interleave(punctured_data, interleaved_data, frame, d_ofdm); interleave(punctured_data, interleaved_data, frame, d_ofdm);
//std::cout << "interleaved" << std::endl; // std::cout << "interleaved" << std::endl;
// one byte per symbol // one byte per symbol
split_symbols(interleaved_data, symbols, frame, d_ofdm); split_symbols(interleaved_data, symbols, frame, d_ofdm);
@@ -131,12 +137,11 @@ int general_work(int noutput, gr_vector_int& ninput_items,
add_item_tag(0, nitems_written(0), key, value, srcid); add_item_tag(0, nitems_written(0), key, value, srcid);
pmt::pmt_t psdu_bytes = pmt::from_long(psdu_length); pmt::pmt_t psdu_bytes = pmt::from_long(psdu_length);
add_item_tag(0, nitems_written(0), pmt::mp("psdu_len"), add_item_tag(
psdu_bytes, srcid); 0, nitems_written(0), pmt::mp("psdu_len"), psdu_bytes, srcid);
pmt::pmt_t encoding = pmt::from_long(d_ofdm.encoding); pmt::pmt_t encoding = pmt::from_long(d_ofdm.encoding);
add_item_tag(0, nitems_written(0), pmt::mp("encoding"), add_item_tag(0, nitems_written(0), pmt::mp("encoding"), encoding, srcid);
encoding, srcid);
free(data_bits); free(data_bits);
@@ -154,22 +159,23 @@ int general_work(int noutput, gr_vector_int& ninput_items,
std::memcpy(out, d_symbols + d_symbols_offset, i); std::memcpy(out, d_symbols + d_symbols_offset, i);
d_symbols_offset += i; d_symbols_offset += i;
if(d_symbols_offset == d_symbols_len) { if (d_symbols_offset == d_symbols_len) {
d_symbols_offset = 0; d_symbols_offset = 0;
free(d_symbols); free(d_symbols);
d_symbols = 0; d_symbols = 0;
} }
return i; return i;
} }
void set_encoding(Encoding encoding) { void set_encoding(Encoding encoding)
{
std::cout << "MAPPER: encoding: " << encoding << std::endl; std::cout << "MAPPER: encoding: " << encoding << std::endl;
gr::thread::scoped_lock lock(d_mutex); gr::thread::scoped_lock lock(d_mutex);
d_ofdm = ofdm_param(encoding); d_ofdm = ofdm_param(encoding);
} }
private: private:
uint8_t d_scrambler; uint8_t d_scrambler;
@@ -181,7 +187,7 @@ private:
gr::thread::mutex d_mutex; gr::thread::mutex d_mutex;
}; };
mapper::sptr mapper::sptr mapper::make(Encoding mcs, bool debug)
mapper::make(Encoding mcs, bool debug) { {
return gnuradio::get_initial_sptr(new mapper_impl(mcs, debug)); return gnuradio::get_initial_sptr(new mapper_impl(mcs, debug));
} }
+96 -72
View File
@@ -14,42 +14,45 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <ieee802_11/parse_mac.h>
#include "utils.h" #include "utils.h"
#include <ieee802_11/parse_mac.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/block_detail.h> #include <gnuradio/block_detail.h>
#include <gnuradio/io_signature.h>
#include <string> #include <string>
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
class parse_mac_impl : public parse_mac { class parse_mac_impl : public parse_mac
{
public: public:
parse_mac_impl(bool log, bool debug)
parse_mac_impl(bool log, bool debug) : : block("parse_mac",
block("parse_mac",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_log(log), d_last_seq_no(-1), d_log(log),
d_debug(debug) { d_last_seq_no(-1),
d_debug(debug)
{
message_port_register_in(pmt::mp("in")); message_port_register_in(pmt::mp("in"));
set_msg_handler(pmt::mp("in"), boost::bind(&parse_mac_impl::parse, this, boost::placeholders::_1)); set_msg_handler(
pmt::mp("in"),
boost::bind(&parse_mac_impl::parse, this, boost::placeholders::_1));
message_port_register_out(pmt::mp("out")); message_port_register_out(pmt::mp("out"));
} }
~parse_mac_impl() { ~parse_mac_impl() {}
} void parse(pmt::pmt_t pdu)
{
void parse(pmt::pmt_t pdu) { if (pmt::is_eof_object(pdu)) {
if(pmt::is_eof_object(pdu)) {
detail().get()->set_done(true); detail().get()->set_done(true);
return; return;
} else if(pmt::is_symbol(pdu)) { } else if (pmt::is_symbol(pdu)) {
return; return;
} }
@@ -57,24 +60,26 @@ void parse(pmt::pmt_t pdu) {
d_msg = pmt::cdr(pdu); d_msg = pmt::cdr(pdu);
int frame_len = pmt::blob_length(d_msg); int frame_len = pmt::blob_length(d_msg);
mac_header *h = (mac_header*)pmt::blob_data(d_msg); mac_header* h = (mac_header*)pmt::blob_data(d_msg);
mylog(boost::format("length: %1%") % frame_len ); mylog(boost::format("length: %1%") % frame_len);
dout << std::endl << "new mac frame (length " << frame_len << ")" << std::endl; dout << std::endl << "new mac frame (length " << frame_len << ")" << std::endl;
dout << "=========================================" << std::endl; dout << "=========================================" << std::endl;
if(frame_len < 20) { if (frame_len < 20) {
dout << "frame too short to parse (<20)" << std::endl; dout << "frame too short to parse (<20)" << std::endl;
return; return;
} }
d_meta = pmt::dict_add(d_meta, pmt::mp("Duration"), pmt::mp(h->duration)); d_meta = pmt::dict_add(d_meta, pmt::mp("Duration"), pmt::mp(h->duration));
#define HEX(a) std::hex << std::setfill('0') << std::setw(2) << int(a) << std::dec #define HEX(a) std::hex << std::setfill('0') << std::setw(2) << int(a) << std::dec
dout << "duration: " << HEX(h->duration >> 8) << " " << HEX(h->duration & 0xff) << std::endl; dout << "duration: " << HEX(h->duration >> 8) << " " << HEX(h->duration & 0xff)
dout << "frame control: " << HEX(h->frame_control >> 8) << " " << HEX(h->frame_control & 0xff); << std::endl;
dout << "frame control: " << HEX(h->frame_control >> 8) << " "
<< HEX(h->frame_control & 0xff);
switch((h->frame_control >> 2) & 3) { switch ((h->frame_control >> 2) & 3) {
case 0: case 0:
d_meta = pmt::dict_add(d_meta, pmt::mp("Type"), pmt::mp("Management")); d_meta = pmt::dict_add(d_meta, pmt::mp("Type"), pmt::mp("Management"));
@@ -99,43 +104,48 @@ void parse(pmt::pmt_t pdu) {
break; break;
} }
char *frame = (char*)pmt::blob_data(d_msg); char* frame = (char*)pmt::blob_data(d_msg);
// DATA // DATA
if((((h->frame_control) >> 2) & 63) == 2) { if ((((h->frame_control) >> 2) & 63) == 2) {
print_ascii(frame + 24, frame_len - 24); print_ascii(frame + 24, frame_len - 24);
// QoS Data // QoS Data
} else if((((h->frame_control) >> 2) & 63) == 34) { } else if ((((h->frame_control) >> 2) & 63) == 34) {
print_ascii(frame + 26, frame_len - 26); print_ascii(frame + 26, frame_len - 26);
} }
message_port_pub(pmt::mp("out"), pmt::cons(d_meta, d_msg)); message_port_pub(pmt::mp("out"), pmt::cons(d_meta, d_msg));
} }
void parse_management(char *buf, int length) { void parse_management(char* buf, int length)
{
mac_header* h = (mac_header*)buf; mac_header* h = (mac_header*)buf;
if(length < 24) { if (length < 24) {
dout << "too short for a management frame" << std::endl; dout << "too short for a management frame" << std::endl;
return; return;
} }
dout << "Subtype: "; dout << "Subtype: ";
switch(((h->frame_control) >> 4) & 0xf) { switch (((h->frame_control) >> 4) & 0xf) {
case 0: case 0:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Association Request")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Association Request"));
dout << "Association Request"; dout << "Association Request";
break; break;
case 1: case 1:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Association Response")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("Association Response"));
dout << "Association Response"; dout << "Association Response";
break; break;
case 2: case 2:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Reassociation Request")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("Reassociation Request"));
dout << "Reassociation Request"; dout << "Reassociation Request";
break; break;
case 3: case 3:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Reassociation Response")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("Reassociation Response"));
dout << "Reassociation Response"; dout << "Reassociation Response";
break; break;
case 4: case 4:
@@ -147,7 +157,8 @@ void parse_management(char *buf, int length) {
dout << "Probe Response"; dout << "Probe Response";
break; break;
case 6: case 6:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Timing Advertisement")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("Timing Advertisement"));
dout << "Timing Advertisement"; dout << "Timing Advertisement";
break; break;
case 7: case 7:
@@ -157,12 +168,12 @@ void parse_management(char *buf, int length) {
case 8: case 8:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Beacon")); d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Beacon"));
dout << "Beacon" << std::endl; dout << "Beacon" << std::endl;
if(length < 38) { if (length < 38) {
return; return;
} }
{ {
uint8_t* len = (uint8_t*) (buf + 24 + 13); uint8_t* len = (uint8_t*)(buf + 24 + 13);
if(length < 38 + *len) { if (length < 38 + *len) {
return; return;
} }
std::string s(buf + 24 + 14, *len); std::string s(buf + 24 + 14, *len);
@@ -183,7 +194,8 @@ void parse_management(char *buf, int length) {
dout << "Authentication"; dout << "Authentication";
break; break;
case 12: case 12:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Deauthentication")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Deauthentication"));
dout << "Deauthentication"; dout << "Deauthentication";
break; break;
case 13: case 13:
@@ -213,23 +225,24 @@ void parse_management(char *buf, int length) {
address = format_mac_address(h->addr2); address = format_mac_address(h->addr2);
d_meta = pmt::dict_add(d_meta, pmt::mp("Address 2"), pmt::mp(address)); d_meta = pmt::dict_add(d_meta, pmt::mp("Address 2"), pmt::mp(address));
dout << "address 2: "<< address << std::endl; dout << "address 2: " << address << std::endl;
address = format_mac_address(h->addr3); address = format_mac_address(h->addr3);
d_meta = pmt::dict_add(d_meta, pmt::mp("Address 3"), pmt::mp(address)); d_meta = pmt::dict_add(d_meta, pmt::mp("Address 3"), pmt::mp(address));
dout << "address 3: "<< address << std::endl; dout << "address 3: " << address << std::endl;
} }
void parse_data(char *buf, int length) { void parse_data(char* buf, int length)
{
mac_header* h = (mac_header*)buf; mac_header* h = (mac_header*)buf;
if(length < 24) { if (length < 24) {
dout << "too short for a data frame" << std::endl; dout << "too short for a data frame" << std::endl;
return; return;
} }
dout << "Subtype: "; dout << "Subtype: ";
switch(((h->frame_control) >> 4) & 0xf) { switch (((h->frame_control) >> 4) & 0xf) {
case 0: case 0:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Data")); d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Data"));
dout << "Data"; dout << "Data";
@@ -243,7 +256,8 @@ void parse_data(char *buf, int length) {
dout << "Data + CR-Poll"; dout << "Data + CR-Poll";
break; break;
case 3: case 3:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Data + CF-ACK + CF-Poll")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("Data + CF-ACK + CF-Poll"));
dout << "Data + CF-ACK + CF-Poll"; dout << "Data + CF-ACK + CF-Poll";
break; break;
case 4: case 4:
@@ -259,7 +273,8 @@ void parse_data(char *buf, int length) {
dout << "CF-Poll"; dout << "CF-Poll";
break; break;
case 7: case 7:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("CF-ACK + CF-Poll")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("CF-ACK + CF-Poll"));
dout << "CF-ACK + CF-Poll"; dout << "CF-ACK + CF-Poll";
break; break;
case 8: case 8:
@@ -267,15 +282,18 @@ void parse_data(char *buf, int length) {
dout << "QoS Data"; dout << "QoS Data";
break; break;
case 9: case 9:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("QoS Data + CF-ACK")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("QoS Data + CF-ACK"));
dout << "QoS Data + CF-ACK"; dout << "QoS Data + CF-ACK";
break; break;
case 10: case 10:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("QoS Data + CF-Poll")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("QoS Data + CF-Poll"));
dout << "QoS Data + CF-Poll"; dout << "QoS Data + CF-Poll";
break; break;
case 11: case 11:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("QoS Data + CF-ACK + CF-Poll")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("QoS Data + CF-ACK + CF-Poll"));
dout << "QoS Data + CF-ACK + CF-Poll"; dout << "QoS Data + CF-ACK + CF-Poll";
break; break;
case 12: case 12:
@@ -291,7 +309,8 @@ void parse_data(char *buf, int length) {
dout << "QoS CF-Poll"; dout << "QoS CF-Poll";
break; break;
case 15: case 15:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("QoS CF-ACK + CF-Poll")); d_meta = pmt::dict_add(
d_meta, pmt::mp("Subtype"), pmt::mp("QoS CF-ACK + CF-Poll"));
dout << "QoS CF-ACK + CF-Poll"; dout << "QoS CF-ACK + CF-Poll";
break; break;
default: default:
@@ -310,15 +329,15 @@ void parse_data(char *buf, int length) {
address = format_mac_address(h->addr2); address = format_mac_address(h->addr2);
d_meta = pmt::dict_add(d_meta, pmt::mp("Address 2"), pmt::mp(address)); d_meta = pmt::dict_add(d_meta, pmt::mp("Address 2"), pmt::mp(address));
dout << "address 2: "<< address << std::endl; dout << "address 2: " << address << std::endl;
address = format_mac_address(h->addr3); address = format_mac_address(h->addr3);
d_meta = pmt::dict_add(d_meta, pmt::mp("Address 3"), pmt::mp(address)); d_meta = pmt::dict_add(d_meta, pmt::mp("Address 3"), pmt::mp(address));
dout << "address 3: "<< address << std::endl; dout << "address 3: " << address << std::endl;
float lost_frames = seq_no - d_last_seq_no - 1; float lost_frames = seq_no - d_last_seq_no - 1;
if(lost_frames < 0) if (lost_frames < 0)
lost_frames += 1 << 12; lost_frames += 1 << 12;
d_meta = pmt::dict_add(d_meta, pmt::mp("Lost frames"), pmt::mp(lost_frames)); d_meta = pmt::dict_add(d_meta, pmt::mp("Lost frames"), pmt::mp(lost_frames));
@@ -329,19 +348,22 @@ void parse_data(char *buf, int length) {
// keep track of sequence numbers // keep track of sequence numbers
d_last_seq_no = seq_no; d_last_seq_no = seq_no;
} }
void parse_control(char *buf, int length) { void parse_control(char* buf, int length)
{
mac_header* h = (mac_header*)buf; mac_header* h = (mac_header*)buf;
dout << "Subtype: "; dout << "Subtype: ";
switch(((h->frame_control) >> 4) & 0xf) { switch (((h->frame_control) >> 4) & 0xf) {
case 7: case 7:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Control Wrapper")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Control Wrapper"));
dout << "Control Wrapper"; dout << "Control Wrapper";
break; break;
case 8: case 8:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Block ACK Request")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("Block ACK Request"));
dout << "Block ACK Request"; dout << "Block ACK Request";
break; break;
case 9: case 9:
@@ -369,7 +391,8 @@ void parse_control(char *buf, int length) {
dout << "CF-End"; dout << "CF-End";
break; break;
case 15: case 15:
d_meta = pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("CF-End + CF-ACK")); d_meta =
pmt::dict_add(d_meta, pmt::mp("Subtype"), pmt::mp("CF-End + CF-ACK"));
dout << "CF-End + CF-ACK"; dout << "CF-End + CF-ACK";
break; break;
default: default:
@@ -386,32 +409,34 @@ void parse_control(char *buf, int length) {
address = format_mac_address(h->addr2); address = format_mac_address(h->addr2);
d_meta = pmt::dict_add(d_meta, pmt::mp("TA"), pmt::mp(address)); d_meta = pmt::dict_add(d_meta, pmt::mp("TA"), pmt::mp(address));
dout << "TA: "<< address << std::endl; dout << "TA: " << address << std::endl;
} }
std::string format_mac_address(uint8_t *addr) { std::string format_mac_address(uint8_t* addr)
{
std::stringstream str; std::stringstream str;
str << std::setfill('0') << std::hex << std::setw(2) << (int)addr[0]; str << std::setfill('0') << std::hex << std::setw(2) << (int)addr[0];
for(int i = 1; i < 6; i++) { for (int i = 1; i < 6; i++) {
str << ":" << (int)addr[i]; str << ":" << (int)addr[i];
} }
return str.str(); return str.str();
} }
void print_ascii(char* buf, int length) { void print_ascii(char* buf, int length)
{
for(int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if((buf[i] > 31) && (buf[i] < 127)) { if ((buf[i] > 31) && (buf[i] < 127)) {
dout << buf[i]; dout << buf[i];
} else { } else {
dout << "."; dout << ".";
} }
} }
dout << std::endl; dout << std::endl;
} }
private: private:
bool d_log; bool d_log;
@@ -421,8 +446,7 @@ private:
pmt::pmt_t d_msg; pmt::pmt_t d_msg;
}; };
parse_mac::sptr parse_mac::sptr parse_mac::make(bool log, bool debug)
parse_mac::make(bool log, bool debug) { {
return gnuradio::get_initial_sptr(new parse_mac_impl(log, debug)); return gnuradio::get_initial_sptr(new parse_mac_impl(log, debug));
} }
+37 -34
View File
@@ -21,12 +21,12 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
signal_field::sptr signal_field::sptr signal_field::make()
signal_field::make() { {
return signal_field::sptr(new signal_field_impl()); return signal_field::sptr(new signal_field_impl());
} }
signal_field::signal_field() : packet_header_default(48, "packet_len") {}; signal_field::signal_field() : packet_header_default(48, "packet_len"){};
signal_field_impl::signal_field_impl() : packet_header_default(48, "packet_len") {} signal_field_impl::signal_field_impl() : packet_header_default(48, "packet_len") {}
@@ -35,37 +35,38 @@ signal_field_impl::signal_field_impl() : packet_header_default(48, "packet_len")
signal_field_impl::~signal_field_impl() {} signal_field_impl::~signal_field_impl() {}
int 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); }
return (b & (1 << i) ? 1 : 0);
}
void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofdm_param &ofdm) { void signal_field_impl::generate_signal_field(char* out,
frame_param& frame,
ofdm_param& ofdm)
{
//data bits of the signal header // data bits of the signal header
char *signal_header = (char *) malloc(sizeof(char) * 24); char* signal_header = (char*)malloc(sizeof(char) * 24);
//signal header after... // signal header after...
//convolutional encoding // convolutional encoding
char *encoded_signal_header = (char *) malloc(sizeof(char) * 48); char* encoded_signal_header = (char*)malloc(sizeof(char) * 48);
//interleaving // interleaving
char *interleaved_signal_header = (char *) malloc(sizeof(char) * 48); char* interleaved_signal_header = (char*)malloc(sizeof(char) * 48);
int length = frame.psdu_size; int length = frame.psdu_size;
// first 4 bits represent the modulation and coding scheme // first 4 bits represent the modulation and coding scheme
signal_header[ 0] = get_bit(ofdm.rate_field, 3); signal_header[0] = get_bit(ofdm.rate_field, 3);
signal_header[ 1] = get_bit(ofdm.rate_field, 2); signal_header[1] = get_bit(ofdm.rate_field, 2);
signal_header[ 2] = get_bit(ofdm.rate_field, 1); signal_header[2] = get_bit(ofdm.rate_field, 1);
signal_header[ 3] = get_bit(ofdm.rate_field, 0); signal_header[3] = get_bit(ofdm.rate_field, 0);
// 5th bit is reserved and must be set to 0 // 5th bit is reserved and must be set to 0
signal_header[ 4] = 0; signal_header[4] = 0;
// then 12 bits represent the length // then 12 bits represent the length
signal_header[ 5] = get_bit(length, 0); signal_header[5] = get_bit(length, 0);
signal_header[ 6] = get_bit(length, 1); signal_header[6] = get_bit(length, 1);
signal_header[ 7] = get_bit(length, 2); signal_header[7] = get_bit(length, 2);
signal_header[ 8] = get_bit(length, 3); signal_header[8] = get_bit(length, 3);
signal_header[ 9] = get_bit(length, 4); signal_header[9] = get_bit(length, 4);
signal_header[10] = get_bit(length, 5); signal_header[10] = get_bit(length, 5);
signal_header[11] = get_bit(length, 6); signal_header[11] = get_bit(length, 6);
signal_header[12] = get_bit(length, 7); signal_header[12] = get_bit(length, 7);
@@ -73,10 +74,10 @@ void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofd
signal_header[14] = get_bit(length, 9); signal_header[14] = get_bit(length, 9);
signal_header[15] = get_bit(length, 10); signal_header[15] = get_bit(length, 10);
signal_header[16] = get_bit(length, 11); signal_header[16] = get_bit(length, 11);
//18-th bit is the parity bit for the first 17 bits // 18-th bit is the parity bit for the first 17 bits
int sum = 0; int sum = 0;
for(int i = 0; i < 17; i++) { for (int i = 0; i < 17; i++) {
if(signal_header[i]) { if (signal_header[i]) {
sum++; sum++;
} }
} }
@@ -100,7 +101,9 @@ void signal_field_impl::generate_signal_field(char *out, frame_param &frame, ofd
free(interleaved_signal_header); free(interleaved_signal_header);
} }
bool 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; bool encoding_found = false;
@@ -109,18 +112,18 @@ bool signal_field_impl::header_formatter(long packet_len, unsigned char *out, co
int len = 0; int len = 0;
// read tags // read tags
for(int i = 0; i < tags.size(); i++) { for (int i = 0; i < tags.size(); i++) {
if(pmt::eq(tags[i].key, pmt::mp("encoding"))) { if (pmt::eq(tags[i].key, pmt::mp("encoding"))) {
encoding_found = true; encoding_found = true;
encoding = pmt::to_long(tags[i].value); encoding = pmt::to_long(tags[i].value);
} else if(pmt::eq(tags[i].key, pmt::mp("psdu_len"))) { } else if (pmt::eq(tags[i].key, pmt::mp("psdu_len"))) {
len_found = true; len_found = true;
len = pmt::to_long(tags[i].value); len = pmt::to_long(tags[i].value);
} }
} }
// check if all tags are present // check if all tags are present
if( (!encoding_found) || (!len_found)) { if ((!encoding_found) || (!len_found)) {
return false; return false;
} }
@@ -131,8 +134,8 @@ bool signal_field_impl::header_formatter(long packet_len, unsigned char *out, co
return true; return true;
} }
bool signal_field_impl::header_parser( bool signal_field_impl::header_parser(const unsigned char* in, std::vector<tag_t>& tags)
const unsigned char *in, std::vector<tag_t> &tags) { {
throw std::runtime_error("not implemented yet"); throw std::runtime_error("not implemented yet");
return false; return false;
+6 -7
View File
@@ -18,8 +18,8 @@
#ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H #ifndef INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H
#define INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H #define INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H
#include <ieee802_11/signal_field.h>
#include "utils.h" #include "utils.h"
#include <ieee802_11/signal_field.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -30,18 +30,17 @@ public:
signal_field_impl(); signal_field_impl();
~signal_field_impl(); ~signal_field_impl();
bool header_formatter(long packet_len, unsigned char *out, bool
const std::vector<tag_t> &tags); header_formatter(long packet_len, unsigned char* out, const std::vector<tag_t>& tags);
bool header_parser(const unsigned char* header, std::vector<tag_t>& tags);
bool header_parser(const unsigned char *header,
std::vector<tag_t> &tags);
private: private:
int get_bit(int b, int i); int get_bit(int b, int i);
void generate_signal_field(char *out, frame_param &frame, ofdm_param &ofdm); void generate_signal_field(char* out, frame_param& frame, ofdm_param& ofdm);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
} // namespace gr } // namespace gr
#endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H */ #endif /* INCLUDED_IEEE802_11_SIGNAL_FIELD_IMPL_H */
+90 -66
View File
@@ -14,11 +14,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <ieee802_11/sync_long.h>
#include "utils.h" #include "utils.h"
#include <gnuradio/io_signature.h>
#include <gnuradio/filter/fir_filter.h>
#include <gnuradio/fft/fft.h> #include <gnuradio/fft/fft.h>
#include <gnuradio/filter/fir_filter.h>
#include <gnuradio/io_signature.h>
#include <ieee802_11/sync_long.h>
#include <list> #include <list>
#include <tuple> #include <tuple>
@@ -27,14 +27,18 @@ using namespace gr::ieee802_11;
using namespace std; using namespace std;
bool compare_abs(const std::pair<gr_complex, int>& first, const std::pair<gr_complex, int>& second) { bool compare_abs(const std::pair<gr_complex, int>& first,
const std::pair<gr_complex, int>& second)
{
return abs(get<0>(first)) > abs(get<0>(second)); return abs(get<0>(first)) > abs(get<0>(second));
} }
class sync_long_impl : public sync_long { class sync_long_impl : public sync_long
{
public: public:
sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("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::make2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_fir(gr::filter::kernel::fir_filter_ccc(1, LONG)), d_fir(gr::filter::kernel::fir_filter_ccc(1, LONG)),
@@ -42,27 +46,27 @@ sync_long_impl(unsigned int sync_length, bool log, bool debug) : block("sync_lon
d_debug(debug), d_debug(debug),
d_offset(0), d_offset(0),
d_state(SYNC), d_state(SYNC),
SYNC_LENGTH(sync_length) { SYNC_LENGTH(sync_length)
{
set_tag_propagation_policy(block::TPP_DONT); set_tag_propagation_policy(block::TPP_DONT);
d_correlation = gr::fft::malloc_complex(8192); d_correlation = gr::fft::malloc_complex(8192);
} }
~sync_long_impl(){ ~sync_long_impl() { gr::fft::free(d_correlation); }
gr::fft::free(d_correlation);
}
int general_work (int noutput, gr_vector_int& ninput_items, int general_work(int noutput,
gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) { gr_vector_void_star& output_items)
{
const gr_complex *in = (const gr_complex*)input_items[0]; const gr_complex* in = (const gr_complex*)input_items[0];
const gr_complex *in_delayed = (const gr_complex*)input_items[1]; const gr_complex* in_delayed = (const gr_complex*)input_items[1];
gr_complex *out = (gr_complex*)output_items[0]; gr_complex* out = (gr_complex*)output_items[0];
dout << "LONG ninput[0] " << ninput_items[0] << " ninput[1] " << dout << "LONG ninput[0] " << ninput_items[0] << " ninput[1] " << ninput_items[1]
ninput_items[1] << " noutput " << noutput << << " noutput " << noutput << " state " << d_state << std::endl;
" state " << d_state << std::endl;
int ninput = std::min(std::min(ninput_items[0], ninput_items[1]), 8192); int ninput = std::min(std::min(ninput_items[0], ninput_items[1]), 8192);
@@ -73,13 +77,13 @@ int general_work (int noutput, gr_vector_int& ninput_items,
const uint64_t offset = d_tags.front().offset; const uint64_t offset = d_tags.front().offset;
if(offset > nread) { if (offset > nread) {
ninput = offset - nread; ninput = offset - nread;
} else { } else {
if(d_offset && (d_state == SYNC)) { if (d_offset && (d_state == SYNC)) {
throw std::runtime_error("wtf"); throw std::runtime_error("wtf");
} }
if(d_state == COPY) { if (d_state == COPY) {
d_state = RESET; d_state = RESET;
} }
d_freq_offset_short = pmt::to_double(d_tags.front().value); d_freq_offset_short = pmt::to_double(d_tags.front().value);
@@ -90,19 +94,20 @@ int general_work (int noutput, gr_vector_int& ninput_items,
int i = 0; int i = 0;
int o = 0; int o = 0;
switch(d_state) { switch (d_state) {
case SYNC: case SYNC:
d_fir.filterN(d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - 63, 0))); d_fir.filterN(
d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - 63, 0)));
while(i + 63 < ninput) { while (i + 63 < ninput) {
d_cor.push_back(pair<gr_complex, int>(d_correlation[i], d_offset)); d_cor.push_back(pair<gr_complex, int>(d_correlation[i], d_offset));
i++; i++;
d_offset++; d_offset++;
if(d_offset == SYNC_LENGTH) { if (d_offset == SYNC_LENGTH) {
search_frame_start(); search_frame_start();
mylog(boost::format("LONG: frame start at %1%") % d_frame_start); mylog(boost::format("LONG: frame start at %1%") % d_frame_start);
d_offset = 0; d_offset = 0;
@@ -116,18 +121,19 @@ int general_work (int noutput, gr_vector_int& ninput_items,
break; break;
case COPY: case COPY:
while(i < ninput && o < noutput) { while (i < ninput && o < noutput) {
int rel = d_offset - d_frame_start; int rel = d_offset - d_frame_start;
if(!rel) { if (!rel) {
add_item_tag(0, nitems_written(0), add_item_tag(0,
nitems_written(0),
pmt::string_to_symbol("wifi_start"), pmt::string_to_symbol("wifi_start"),
pmt::from_double(d_freq_offset_short - d_freq_offset), pmt::from_double(d_freq_offset_short - d_freq_offset),
pmt::string_to_symbol(name())); pmt::string_to_symbol(name()));
} }
if(rel >= 0 && (rel < 128 || ((rel - 128) % 80) > 15)) { if (rel >= 0 && (rel < 128 || ((rel - 128) % 80) > 15)) {
out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset)); out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset));
o++; o++;
} }
@@ -139,8 +145,8 @@ int general_work (int noutput, gr_vector_int& ninput_items,
break; break;
case RESET: { case RESET: {
while(o < noutput) { while (o < noutput) {
if(((d_count + o) % 64) == 0) { if (((d_count + o) % 64) == 0) {
d_offset = 0; d_offset = 0;
d_state = SYNC; d_state = SYNC;
break; break;
@@ -160,13 +166,14 @@ int general_work (int noutput, gr_vector_int& ninput_items,
consume(0, i); consume(0, i);
consume(1, i); consume(1, i);
return o; return o;
} }
void forecast (int noutput_items, gr_vector_int &ninput_items_required) { void forecast(int noutput_items, gr_vector_int& ninput_items_required)
{
// in sync state we need at least a symbol to correlate // in sync state we need at least a symbol to correlate
// with the pattern // with the pattern
if(d_state == SYNC) { if (d_state == SYNC) {
ninput_items_required[0] = 64; ninput_items_required[0] = 64;
ninput_items_required[1] = 64; ninput_items_required[1] = 64;
@@ -174,26 +181,27 @@ void forecast (int noutput_items, gr_vector_int &ninput_items_required) {
ninput_items_required[0] = noutput_items; ninput_items_required[0] = noutput_items;
ninput_items_required[1] = noutput_items; ninput_items_required[1] = noutput_items;
} }
} }
void search_frame_start() { void search_frame_start()
{
// sort list (highest correlation first) // sort list (highest correlation first)
assert(d_cor.size() == SYNC_LENGTH); assert(d_cor.size() == SYNC_LENGTH);
d_cor.sort(compare_abs); d_cor.sort(compare_abs);
// copy list in vector for nicer access // copy list in vector for nicer access
vector<pair<gr_complex, int> > vec(d_cor.begin(), d_cor.end()); vector<pair<gr_complex, int>> vec(d_cor.begin(), d_cor.end());
d_cor.clear(); d_cor.clear();
// in case we don't find anything use SYNC_LENGTH // in case we don't find anything use SYNC_LENGTH
d_frame_start = SYNC_LENGTH; d_frame_start = SYNC_LENGTH;
for(int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for(int k = i + 1; k < 4; k++) { for (int k = i + 1; k < 4; k++) {
gr_complex first; gr_complex first;
gr_complex second; gr_complex second;
if(get<1>(vec[i]) > get<1>(vec[k])) { if (get<1>(vec[i]) > get<1>(vec[k])) {
first = get<0>(vec[k]); first = get<0>(vec[k]);
second = get<0>(vec[i]); second = get<0>(vec[i]);
} else { } else {
@@ -201,33 +209,33 @@ void search_frame_start() {
second = get<0>(vec[k]); second = get<0>(vec[k]);
} }
int diff = abs(get<1>(vec[i]) - get<1>(vec[k])); int diff = abs(get<1>(vec[i]) - get<1>(vec[k]));
if(diff == 64) { if (diff == 64) {
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); d_frame_start = min(get<1>(vec[i]), get<1>(vec[k]));
d_freq_offset = arg(first * conj(second)) / 64; d_freq_offset = arg(first * conj(second)) / 64;
// nice match found, return immediately // nice match found, return immediately
return; return;
} else if(diff == 63) { } else if (diff == 63) {
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); d_frame_start = min(get<1>(vec[i]), get<1>(vec[k]));
d_freq_offset = arg(first * conj(second)) / 63; d_freq_offset = arg(first * conj(second)) / 63;
} else if(diff == 65) { } else if (diff == 65) {
d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); d_frame_start = min(get<1>(vec[i]), get<1>(vec[k]));
d_freq_offset = arg(first * conj(second)) / 65; d_freq_offset = arg(first * conj(second)) / 65;
} }
} }
} }
} }
private: private:
enum {SYNC, COPY, RESET} d_state; enum { SYNC, COPY, RESET } d_state;
int d_count; int d_count;
int d_offset; int d_offset;
int d_frame_start; int d_frame_start;
float d_freq_offset; float d_freq_offset;
double d_freq_offset_short; double d_freq_offset_short;
gr_complex *d_correlation; gr_complex* d_correlation;
list<pair<gr_complex, int> > d_cor; list<pair<gr_complex, int>> d_cor;
std::vector<gr::tag_t> d_tags; std::vector<gr::tag_t> d_tags;
gr::filter::kernel::fir_filter_ccc d_fir; gr::filter::kernel::fir_filter_ccc d_fir;
@@ -238,28 +246,44 @@ private:
static const std::vector<gr_complex> LONG; static const std::vector<gr_complex> LONG;
}; };
sync_long::sptr sync_long::sptr sync_long::make(unsigned int sync_length, bool log, bool debug)
sync_long::make(unsigned int sync_length, bool log, bool debug) { {
return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, debug)); return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, debug));
} }
const std::vector<gr_complex> 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.0455, -1.0679), gr_complex(0.3528, -0.9865),
gr_complex( 0.5309, -0.7784), gr_complex(-1.0218, -0.4897), gr_complex(-0.3401, -0.9423), gr_complex( 0.8657, -0.2298), gr_complex(0.8594, 0.7348), gr_complex(0.1874, 0.2475),
gr_complex( 0.4734, 0.0362), gr_complex( 0.0088, -1.0207), gr_complex(-1.2142, -0.4205), gr_complex( 0.2172, -0.5195), gr_complex(0.5309, -0.7784), gr_complex(-1.0218, -0.4897),
gr_complex( 0.5207, -0.1326), gr_complex(-0.1995, 1.4259), gr_complex( 1.0583, -0.0363), gr_complex( 0.5547, -0.5547), gr_complex(-0.3401, -0.9423), gr_complex(0.8657, -0.2298),
gr_complex( 0.3277, 0.8728), gr_complex(-0.5077, 0.3488), gr_complex(-1.1650, 0.5789), gr_complex( 0.7297, 0.8197), gr_complex(0.4734, 0.0362), gr_complex(0.0088, -1.0207),
gr_complex( 0.6173, 0.1253), gr_complex(-0.5353, 0.7214), gr_complex(-0.5011, -0.1935), gr_complex(-0.3110, -1.3392), gr_complex(-1.2142, -0.4205), gr_complex(0.2172, -0.5195),
gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), gr_complex( 0.6663, -0.6571), gr_complex(-0.0249, 0.4773), gr_complex(0.5207, -0.1326), gr_complex(-0.1995, 1.4259),
gr_complex(-0.8155, 1.0218), gr_complex( 0.8140, 0.9396), gr_complex( 0.1090, 0.8662), gr_complex(-1.3868, -0.0000), gr_complex(1.0583, -0.0363), gr_complex(0.5547, -0.5547),
gr_complex( 0.1090, -0.8662), gr_complex( 0.8140, -0.9396), gr_complex(-0.8155, -1.0218), gr_complex(-0.0249, -0.4773), gr_complex(0.3277, 0.8728), gr_complex(-0.5077, 0.3488),
gr_complex( 0.6663, 0.6571), gr_complex(-1.1300, 0.1820), gr_complex(-1.0818, 0.1470), gr_complex(-0.3110, 1.3392), gr_complex(-1.1650, 0.5789), gr_complex(0.7297, 0.8197),
gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), gr_complex( 0.6173, -0.1253), gr_complex( 0.7297, -0.8197), gr_complex(0.6173, 0.1253), gr_complex(-0.5353, 0.7214),
gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), gr_complex( 0.3277, -0.8728), gr_complex( 0.5547, 0.5547), gr_complex(-0.5011, -0.1935), gr_complex(-0.3110, -1.3392),
gr_complex( 1.0583, 0.0363), gr_complex(-0.1995, -1.4259), gr_complex( 0.5207, 0.1326), gr_complex( 0.2172, 0.5195), gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820),
gr_complex(-1.2142, 0.4205), gr_complex( 0.0088, 1.0207), gr_complex( 0.4734, -0.0362), gr_complex( 0.8657, 0.2298), gr_complex(0.6663, -0.6571), gr_complex(-0.0249, 0.4773),
gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), gr_complex( 0.5309, 0.7784), gr_complex( 0.1874, -0.2475), gr_complex(-0.8155, 1.0218), gr_complex(0.8140, 0.9396),
gr_complex( 0.8594, -0.7348), gr_complex( 0.3528, 0.9865), gr_complex(-0.0455, 1.0679), gr_complex( 1.3868, -0.0000), gr_complex(0.1090, 0.8662), gr_complex(-1.3868, -0.0000),
gr_complex(0.1090, -0.8662), gr_complex(0.8140, -0.9396),
gr_complex(-0.8155, -1.0218), gr_complex(-0.0249, -0.4773),
gr_complex(0.6663, 0.6571), gr_complex(-1.1300, 0.1820),
gr_complex(-1.0818, 0.1470), gr_complex(-0.3110, 1.3392),
gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214),
gr_complex(0.6173, -0.1253), gr_complex(0.7297, -0.8197),
gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488),
gr_complex(0.3277, -0.8728), gr_complex(0.5547, 0.5547),
gr_complex(1.0583, 0.0363), gr_complex(-0.1995, -1.4259),
gr_complex(0.5207, 0.1326), gr_complex(0.2172, 0.5195),
gr_complex(-1.2142, 0.4205), gr_complex(0.0088, 1.0207),
gr_complex(0.4734, -0.0362), gr_complex(0.8657, 0.2298),
gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897),
gr_complex(0.5309, 0.7784), gr_complex(0.1874, -0.2475),
gr_complex(0.8594, -0.7348), gr_complex(0.3528, 0.9865),
gr_complex(-0.0455, 1.0679), gr_complex(1.3868, -0.0000),
}; };
+43 -32
View File
@@ -14,9 +14,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <ieee802_11/sync_short.h>
#include <gnuradio/io_signature.h>
#include "utils.h" #include "utils.h"
#include <gnuradio/io_signature.h>
#include <ieee802_11/sync_short.h>
#include <iostream> #include <iostream>
@@ -25,12 +25,14 @@ using namespace gr::ieee802_11;
static const int MIN_GAP = 480; static const int MIN_GAP = 480;
static const int MAX_SAMPLES = 540 * 80; static const int MAX_SAMPLES = 540 * 80;
class sync_short_impl : public sync_short { class sync_short_impl : public sync_short
{
public: public:
sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug) : sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug)
block("sync_short", : block("sync_short",
gr::io_signature::make3(3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)), gr::io_signature::make3(
3, 3, sizeof(gr_complex), sizeof(gr_complex), sizeof(float)),
gr::io_signature::make(1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_log(log), d_log(log),
d_debug(debug), d_debug(debug),
@@ -39,33 +41,38 @@ sync_short_impl(double threshold, unsigned int min_plateau, bool log, bool debug
d_freq_offset(0), d_freq_offset(0),
d_copied(0), d_copied(0),
MIN_PLATEAU(min_plateau), MIN_PLATEAU(min_plateau),
d_threshold(threshold) { d_threshold(threshold)
{
set_tag_propagation_policy(block::TPP_DONT); set_tag_propagation_policy(block::TPP_DONT);
} }
int general_work (int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items,
gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) { gr_vector_void_star& output_items)
{
const gr_complex *in = (const gr_complex*)input_items[0]; const gr_complex* in = (const gr_complex*)input_items[0];
const gr_complex *in_abs = (const gr_complex*)input_items[1]; const gr_complex* in_abs = (const gr_complex*)input_items[1];
const float *in_cor = (const float*)input_items[2]; const float* in_cor = (const float*)input_items[2];
gr_complex *out = (gr_complex*)output_items[0]; gr_complex* out = (gr_complex*)output_items[0];
int noutput = noutput_items; int noutput = noutput_items;
int ninput = std::min(std::min(ninput_items[0], ninput_items[1]), ninput_items[2]); int ninput =
std::min(std::min(ninput_items[0], ninput_items[1]), ninput_items[2]);
// dout << "SHORT noutput : " << noutput << " ninput: " << ninput_items[0] << std::endl; // dout << "SHORT noutput : " << noutput << " ninput: " << ninput_items[0] <<
// std::endl;
switch(d_state) { switch (d_state) {
case SEARCH: { case SEARCH: {
int i; int i;
for(i = 0; i < ninput; i++) { for (i = 0; i < ninput; i++) {
if(in_cor[i] > d_threshold) { if (in_cor[i] > d_threshold) {
if(d_plateau < MIN_PLATEAU) { if (d_plateau < MIN_PLATEAU) {
d_plateau++; d_plateau++;
} else { } else {
@@ -89,17 +96,18 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
case COPY: { case COPY: {
int o = 0; int o = 0;
while( o < ninput && o < noutput && d_copied < MAX_SAMPLES) { while (o < ninput && o < noutput && d_copied < MAX_SAMPLES) {
if(in_cor[o] > d_threshold) { if (in_cor[o] > d_threshold) {
if(d_plateau < MIN_PLATEAU) { if (d_plateau < MIN_PLATEAU) {
d_plateau++; d_plateau++;
// there's another frame // there's another frame
} else if(d_copied > MIN_GAP) { } else if (d_copied > MIN_GAP) {
d_copied = 0; d_copied = 0;
d_plateau = 0; d_plateau = 0;
d_freq_offset = arg(in_abs[o]) / 16; d_freq_offset = arg(in_abs[o]) / 16;
insert_tag(nitems_written(0) + o, d_freq_offset, nitems_read(0) + o); insert_tag(
nitems_written(0) + o, d_freq_offset, nitems_read(0) + o);
dout << "SHORT Frame!" << std::endl; dout << "SHORT Frame!" << std::endl;
break; break;
} }
@@ -113,7 +121,7 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
d_copied++; d_copied++;
} }
if(d_copied == MAX_SAMPLES) { if (d_copied == MAX_SAMPLES) {
d_state = SEARCH; d_state = SEARCH;
} }
@@ -126,19 +134,20 @@ int general_work (int noutput_items, gr_vector_int& ninput_items,
throw std::runtime_error("sync short: unknown state"); throw std::runtime_error("sync short: unknown state");
return 0; return 0;
} }
void insert_tag(uint64_t item, double freq_offset, uint64_t input_item) { void insert_tag(uint64_t item, double freq_offset, uint64_t input_item)
{
mylog(boost::format("frame start at in: %2% out: %1%") % item % input_item); mylog(boost::format("frame start at in: %2% out: %1%") % item % input_item);
const pmt::pmt_t key = pmt::string_to_symbol("wifi_start"); const pmt::pmt_t key = pmt::string_to_symbol("wifi_start");
const pmt::pmt_t value = pmt::from_double(freq_offset); const pmt::pmt_t value = pmt::from_double(freq_offset);
const pmt::pmt_t srcid = pmt::string_to_symbol(name()); const pmt::pmt_t srcid = pmt::string_to_symbol(name());
add_item_tag(0, item, key, value, srcid); add_item_tag(0, item, key, value, srcid);
} }
private: private:
enum {SEARCH, COPY} d_state; enum { SEARCH, COPY } d_state;
int d_copied; int d_copied;
int d_plateau; int d_plateau;
float d_freq_offset; float d_freq_offset;
@@ -149,6 +158,8 @@ private:
}; };
sync_short::sptr sync_short::sptr
sync_short::make(double threshold, unsigned int min_plateau, bool log, bool debug) { 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)); {
return gnuradio::get_initial_sptr(
new sync_short_impl(threshold, min_plateau, log, debug));
} }
+40 -29
View File
@@ -16,14 +16,15 @@
*/ */
#include "utils.h" #include "utils.h"
#include <math.h>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <math.h>
ofdm_param::ofdm_param(Encoding e) { ofdm_param::ofdm_param(Encoding e)
{
encoding = e; encoding = e;
switch(e) { switch (e) {
case BPSK_1_2: case BPSK_1_2:
n_bpsc = 1; n_bpsc = 1;
n_cbps = 48; n_cbps = 48;
@@ -86,8 +87,8 @@ ofdm_param::ofdm_param(Encoding e) {
} }
void void ofdm_param::print()
ofdm_param::print() { {
std::cout << "OFDM Parameters:" << std::endl; std::cout << "OFDM Parameters:" << std::endl;
std::cout << "endcoding :" << encoding << std::endl; std::cout << "endcoding :" << encoding << std::endl;
std::cout << "rate_field :" << (int)rate_field << std::endl; std::cout << "rate_field :" << (int)rate_field << std::endl;
@@ -97,12 +98,13 @@ ofdm_param::print() {
} }
frame_param::frame_param(ofdm_param &ofdm, int psdu_length) { frame_param::frame_param(ofdm_param& ofdm, int psdu_length)
{
psdu_size = psdu_length; psdu_size = psdu_length;
// number of symbols (17-11) // number of symbols (17-11)
n_sym = (int) ceil((16 + 8 * psdu_size + 6) / (double) ofdm.n_dbps); n_sym = (int)ceil((16 + 8 * psdu_size + 6) / (double)ofdm.n_dbps);
n_data_bits = n_sym * ofdm.n_dbps; n_data_bits = n_sym * ofdm.n_dbps;
@@ -111,8 +113,8 @@ frame_param::frame_param(ofdm_param &ofdm, int psdu_length) {
n_encoded_bits = n_sym * ofdm.n_cbps; n_encoded_bits = n_sym * ofdm.n_cbps;
} }
void void frame_param::print()
frame_param::print() { {
std::cout << "FRAME Parameters:" << std::endl; std::cout << "FRAME Parameters:" << std::endl;
std::cout << "psdu_size: " << psdu_size << std::endl; std::cout << "psdu_size: " << psdu_size << std::endl;
std::cout << "n_sym: " << n_sym << std::endl; std::cout << "n_sym: " << n_sym << std::endl;
@@ -122,7 +124,8 @@ frame_param::print() {
} }
void scramble(const char *in, char *out, frame_param &frame, char initial_state) { void scramble(const char* in, char* out, frame_param& frame, char initial_state)
{
int state = initial_state; int state = initial_state;
int feedback; int feedback;
@@ -136,15 +139,17 @@ void scramble(const char *in, char *out, frame_param &frame, char initial_state)
} }
void reset_tail_bits(char *scrambled_data, frame_param &frame) { void reset_tail_bits(char* scrambled_data, frame_param& frame)
{
memset(scrambled_data + frame.n_data_bits - frame.n_pad - 6, 0, 6 * sizeof(char)); memset(scrambled_data + frame.n_data_bits - frame.n_pad - 6, 0, 6 * sizeof(char));
} }
int ones(int n) { int ones(int n)
{
int sum = 0; int sum = 0;
for(int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if(n & (1 << i)) { if (n & (1 << i)) {
sum++; sum++;
} }
} }
@@ -152,11 +157,12 @@ int ones(int n) {
} }
void convolutional_encoding(const char *in, char *out, frame_param &frame) { void convolutional_encoding(const char* in, char* out, frame_param& frame)
{
int state = 0; int state = 0;
for(int i = 0; i < frame.n_data_bits; i++) { for (int i = 0; i < frame.n_data_bits; i++) {
assert(in[i] == 0 || in[i] == 1); assert(in[i] == 0 || in[i] == 1);
state = ((state << 1) & 0x7e) | in[i]; state = ((state << 1) & 0x7e) | in[i];
out[i * 2] = ones(state & 0155) % 2; out[i * 2] = ones(state & 0155) % 2;
@@ -165,12 +171,13 @@ void convolutional_encoding(const char *in, char *out, frame_param &frame) {
} }
void puncturing(const char *in, char *out, frame_param &frame, ofdm_param &ofdm) { void puncturing(const char* in, char* out, frame_param& frame, ofdm_param& ofdm)
{
int mod; int mod;
for (int i = 0; i < frame.n_data_bits * 2; i++) { for (int i = 0; i < frame.n_data_bits * 2; i++) {
switch(ofdm.encoding) { switch (ofdm.encoding) {
case BPSK_1_2: case BPSK_1_2:
case QPSK_1_2: case QPSK_1_2:
case QAM16_1_2: case QAM16_1_2:
@@ -203,24 +210,26 @@ void puncturing(const char *in, char *out, frame_param &frame, ofdm_param &ofdm)
} }
void interleave(const char *in, char *out, frame_param &frame, 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 n_cbps = ofdm.n_cbps;
int first[n_cbps]; int first[n_cbps];
int second[n_cbps]; int second[n_cbps];
int s = std::max(ofdm.n_bpsc / 2, 1); int s = std::max(ofdm.n_bpsc / 2, 1);
for(int j = 0; j < n_cbps; j++) { for (int j = 0; j < n_cbps; j++) {
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s); first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
} }
for(int i = 0; i < n_cbps; i++) { for (int i = 0; i < n_cbps; i++) {
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps)); second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
} }
for(int i = 0; i < frame.n_sym; i++) { for (int i = 0; i < frame.n_sym; i++) {
for(int k = 0; k < n_cbps; k++) { for (int k = 0; k < n_cbps; k++) {
if(reverse) { if (reverse) {
out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k]; out[i * n_cbps + second[first[k]]] = in[i * n_cbps + k];
} else { } else {
out[i * n_cbps + k] = in[i * n_cbps + second[first[k]]]; out[i * n_cbps + k] = in[i * n_cbps + second[first[k]]];
@@ -230,13 +239,14 @@ void interleave(const char *in, char *out, frame_param &frame, ofdm_param &ofdm,
} }
void split_symbols(const char *in, char *out, frame_param &frame, ofdm_param &ofdm) { void split_symbols(const char* in, char* out, frame_param& frame, ofdm_param& ofdm)
{
int symbols = frame.n_sym * 48; int symbols = frame.n_sym * 48;
for (int i = 0; i < symbols; i++) { for (int i = 0; i < symbols; i++) {
out[i] = 0; out[i] = 0;
for(int k = 0; k < ofdm.n_bpsc; k++) { for (int k = 0; k < ofdm.n_bpsc; k++) {
assert(*in == 1 || *in == 0); assert(*in == 1 || *in == 0);
out[i] |= (*in << k); out[i] |= (*in << k);
in++; in++;
@@ -245,14 +255,15 @@ void split_symbols(const char *in, char *out, frame_param &frame, ofdm_param &of
} }
void generate_bits(const char *psdu, char *data_bits, frame_param &frame) { void generate_bits(const char* psdu, char* data_bits, frame_param& frame)
{
// first 16 bits are zero (SERVICE/DATA field) // first 16 bits are zero (SERVICE/DATA field)
memset(data_bits, 0, 16); memset(data_bits, 0, 16);
data_bits += 16; data_bits += 16;
for(int i = 0; i < frame.psdu_size; i++) { for (int i = 0; i < frame.psdu_size; i++) {
for(int b = 0; b < 8; b++) { for (int b = 0; b < 8; b++) {
data_bits[i * 8 + b] = !!(psdu[i] & (1 << b)); data_bits[i * 8 + b] = !!(psdu[i] & (1 << b));
} }
} }
+28 -16
View File
@@ -17,9 +17,9 @@
#ifndef INCLUDED_IEEE802_11_UTILS_H #ifndef INCLUDED_IEEE802_11_UTILS_H
#define INCLUDED_IEEE802_11_UTILS_H #define INCLUDED_IEEE802_11_UTILS_H
#include <gnuradio/config.h>
#include <ieee802_11/api.h> #include <ieee802_11/api.h>
#include <ieee802_11/mapper.h> #include <ieee802_11/mapper.h>
#include <gnuradio/config.h>
#include <cinttypes> #include <cinttypes>
#include <iostream> #include <iostream>
@@ -28,23 +28,29 @@
#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) #define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1)
#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) #define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288)
#define dout d_debug && std::cout #define dout d_debug&& std::cout
#define mylog(msg) do { if(d_log) { GR_LOG_INFO(d_logger, msg); }} while(0); #define mylog(msg) \
do { \
if (d_log) { \
GR_LOG_INFO(d_logger, msg); \
} \
} while (0);
struct mac_header { struct mac_header {
//protocol version, type, subtype, to_ds, from_ds, ... // protocol version, type, subtype, to_ds, from_ds, ...
uint16_t frame_control; uint16_t frame_control;
uint16_t duration; uint16_t duration;
uint8_t addr1[6]; uint8_t addr1[6];
uint8_t addr2[6]; uint8_t addr2[6];
uint8_t addr3[6]; uint8_t addr3[6];
uint16_t seq_nr; uint16_t seq_nr;
}__attribute__((packed)); } __attribute__((packed));
/** /**
* WIFI parameters * WIFI parameters
*/ */
class ofdm_param { class ofdm_param
{
public: public:
ofdm_param(Encoding e); ofdm_param(Encoding e);
@@ -65,9 +71,10 @@ public:
/** /**
* packet specific parameters * packet specific parameters
*/ */
class frame_param { class frame_param
{
public: public:
frame_param(ofdm_param &ofdm, int psdu_length); frame_param(ofdm_param& ofdm, int psdu_length);
// PSDU size in bytes // PSDU size in bytes
int psdu_size; int psdu_size;
// number of OFDM symbols (17-11) // number of OFDM symbols (17-11)
@@ -93,20 +100,25 @@ public:
* will be stored * will be stored
* \param seq sequence number of the frame * \param seq sequence number of the frame
*/ */
void generate_mac_data_frame(const char *msdu, int msdu_size, char **psdu, int *psdu_size, char seq); void generate_mac_data_frame(
const char* msdu, int msdu_size, char** psdu, int* psdu_size, char seq);
void scramble(const char *input, char *out, frame_param &frame, char initial_state); void scramble(const char* input, char* out, frame_param& frame, char initial_state);
void reset_tail_bits(char *scrambled_data, frame_param &frame); void reset_tail_bits(char* scrambled_data, frame_param& frame);
void convolutional_encoding(const char *input, char *out, frame_param &frame); void convolutional_encoding(const char* input, char* out, frame_param& frame);
void puncturing(const char *input, char *out, frame_param &frame, ofdm_param &ofdm); void puncturing(const char* input, char* out, frame_param& frame, ofdm_param& ofdm);
void interleave(const char *input, char *out, frame_param &frame, ofdm_param &ofdm, bool reverse = false); void interleave(const char* input,
char* out,
frame_param& frame,
ofdm_param& ofdm,
bool reverse = false);
void split_symbols(const char *input, char *out, frame_param &frame, 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, frame_param &frame); void generate_bits(const char* psdu, char* data_bits, frame_param& frame);
#endif /* INCLUDED_IEEE802_11_UTILS_H */ #endif /* INCLUDED_IEEE802_11_UTILS_H */
+19 -45
View File
@@ -21,19 +21,16 @@
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
base::base() : base::base() : d_store_pos(0) {}
d_store_pos(0) {
}
base::~base() { base::~base() {}
}
uint8_t* uint8_t* base::depuncture(uint8_t* in)
base::depuncture(uint8_t *in) { {
int count; int count;
int n_cbps = d_ofdm->n_cbps; int n_cbps = d_ofdm->n_cbps;
uint8_t *depunctured; uint8_t* depunctured;
if (d_ntraceback == 5) { if (d_ntraceback == 5) {
count = d_frame->n_sym * n_cbps; count = d_frame->n_sym * n_cbps;
@@ -42,8 +39,8 @@ base::depuncture(uint8_t *in) {
} else { } else {
depunctured = d_depunctured; depunctured = d_depunctured;
count = 0; count = 0;
for(int i = 0; i < d_frame->n_sym; i++) { for (int i = 0; i < d_frame->n_sym; i++) {
for(int k = 0; k < n_cbps; k++) { for (int k = 0; k < n_cbps; k++) {
while (d_depuncture_pattern[count % (2 * d_k)] == 0) { while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
depunctured[count] = 2; depunctured[count] = 2;
count++; count++;
@@ -66,40 +63,17 @@ base::depuncture(uint8_t *in) {
/* Parity lookup table */ /* Parity lookup table */
const unsigned char base::PARTAB[256] = { const unsigned char base::PARTAB[256] = {
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,
1, 0, 0, 1, 0, 1, 1, 0, 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,
1, 0, 0, 1, 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,
0, 1, 1, 0, 1, 0, 0, 1, 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,
1, 0, 0, 1, 0, 1, 1, 0, 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,
0, 1, 1, 0, 1, 0, 0, 1, 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,
0, 1, 1, 0, 1, 0, 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, 0, 1, 0, 1, 1, 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,
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,
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,
}; };
const unsigned char base::PUNCTURE_1_2[2] = {1, 1}; const unsigned char base::PUNCTURE_1_2[2] = { 1, 1 };
const unsigned char base::PUNCTURE_2_3[4] = {1, 1, 1, 0}; const unsigned char base::PUNCTURE_2_3[4] = { 1, 1, 1, 0 };
const unsigned char base::PUNCTURE_3_4[6] = {1, 1, 1, 0, 0, 1}; const unsigned char base::PUNCTURE_3_4[6] = { 1, 1, 1, 0, 0, 1 };
+5 -6
View File
@@ -33,10 +33,9 @@ namespace ieee802_11 {
class base class base
{ {
public: public:
base(); base();
~base(); ~base();
virtual uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) = 0; virtual uint8_t* decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in) = 0;
protected: protected:
// Position in circular buffer where the current decoded byte is stored // Position in circular buffer where the current decoded byte is stored
@@ -48,9 +47,9 @@ protected:
int d_ntraceback; int d_ntraceback;
int d_k; int d_k;
ofdm_param *d_ofdm; ofdm_param* d_ofdm;
frame_param *d_frame; frame_param* d_frame;
const unsigned char *d_depuncture_pattern; const unsigned char* d_depuncture_pattern;
uint8_t d_depunctured[MAX_ENCODED_BITS]; uint8_t d_depunctured[MAX_ENCODED_BITS];
uint8_t d_decoded[MAX_ENCODED_BITS * 3 / 4]; uint8_t d_decoded[MAX_ENCODED_BITS * 3 / 4];
@@ -61,7 +60,7 @@ protected:
static const unsigned char PUNCTURE_3_4[6]; static const unsigned char PUNCTURE_3_4[6];
virtual void reset() = 0; virtual void reset() = 0;
uint8_t* depuncture(uint8_t *in); uint8_t* depuncture(uint8_t* in);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+104 -94
View File
@@ -56,37 +56,39 @@
* would spill over into memory. * would spill over into memory.
*/ */
#define BUTTERFLY(i,sym) { \ #define BUTTERFLY(i, sym) \
int m0,m1,m2,m3; \ { \
int m0, m1, m2, m3; \
/* ACS for 0 branch */ \ /* ACS for 0 branch */ \
m0 = state[i].metric + mets[sym]; /* 2*i */ \ m0 = state[i].metric + mets[sym]; /* 2*i */ \
m1 = state[i+32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \ m1 = state[i + 32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
if(m0 > m1){ \ if (m0 > m1) { \
next[2*i].metric = m0; \ next[2 * i].metric = m0; \
next[2*i].path = state[i].path << 1; \ next[2 * i].path = state[i].path << 1; \
} else { \ } else { \
next[2*i].metric = m1; \ next[2 * i].metric = m1; \
next[2*i].path = (state[i+32].path << 1)|1; \ next[2 * i].path = (state[i + 32].path << 1) | 1; \
} \ } \
/* ACS for 1 branch */ \ /* ACS for 1 branch */ \
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \ m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
m3 = state[i+32].metric + mets[sym]; /* 2*i + 65 */ \ m3 = state[i + 32].metric + mets[sym]; /* 2*i + 65 */ \
if(m2 > m3){ \ if (m2 > m3) { \
next[2*i+1].metric = m2; \ next[2 * i + 1].metric = m2; \
next[2*i+1].path = state[i].path << 1; \ next[2 * i + 1].path = state[i].path << 1; \
} else { \ } else { \
next[2*i+1].metric = m3; \ next[2 * i + 1].metric = m3; \
next[2*i+1].path = (state[i+32].path << 1)|1; \ next[2 * i + 1].path = (state[i + 32].path << 1) | 1; \
} \ } \
} }
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
void void viterbi_decoder::viterbi_butterfly2_generic(unsigned char* symbols,
viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols, unsigned char* mm0,
unsigned char *mm0, unsigned char *mm1, unsigned char *pp0, unsigned char* mm1,
unsigned char *pp1) unsigned char* pp0,
unsigned char* pp1)
{ {
int i, j, k; int i, j, k;
@@ -100,7 +102,8 @@ viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols,
// Operate on 4 symbols (2 bits) at a time // Operate on 4 symbols (2 bits) at a time
unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16]; unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16],
survivor0[16], survivor1[16];
unsigned char metsv[16], metsvm[16]; unsigned char metsv[16], metsvm[16];
unsigned char shift0[16], shift1[16]; unsigned char shift0[16], shift1[16];
unsigned char tmp0[16], tmp1[16]; unsigned char tmp0[16], tmp1[16];
@@ -115,28 +118,27 @@ viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (symbols[0] == 2) { if (symbols[0] == 2) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; metsvm[j] = d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j];
metsv[j] = 1 - metsvm[j]; metsv[j] = 1 - metsvm[j];
} }
} } else if (symbols[1] == 2) {
else if (symbols[1] == 2) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; metsvm[j] = d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j];
metsv[j] = 1 - metsvm[j]; metsv[j] = 1 - metsvm[j];
} }
} } else {
else {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); metsvm[j] = (d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]) +
(d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]);
metsv[j] = 2 - metsvm[j]; metsv[j] = 2 - metsvm[j];
} }
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
m0[j] = metric0[(i*16) + j] + metsv[j]; m0[j] = metric0[(i * 16) + j] + metsv[j];
m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j];
m2[j] = metric0[(i*16) + j] + metsvm[j]; m2[j] = metric0[(i * 16) + j] + metsvm[j];
m3[j] = metric0[((i+2)*16) + j] + metsv[j]; m3[j] = metric0[((i + 2) * 16) + j] + metsv[j];
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
@@ -147,45 +149,45 @@ viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols,
} }
for (j = 0; j < 16; j += 2) { for (j = 0; j < 16; j += 2) {
simd_epi16 = path0[(i*16) + j]; simd_epi16 = path0[(i * 16) + j];
simd_epi16 |= path0[(i*16) + (j+1)] << 8; simd_epi16 |= path0[(i * 16) + (j + 1)] << 8;
simd_epi16 <<= 1; simd_epi16 <<= 1;
shift0[j] = simd_epi16; shift0[j] = simd_epi16;
shift0[j+1] = simd_epi16 >> 8; shift0[j + 1] = simd_epi16 >> 8;
simd_epi16 = path0[((i+2)*16) + j]; simd_epi16 = path0[((i + 2) * 16) + j];
simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8;
simd_epi16 <<= 1; simd_epi16 <<= 1;
shift1[j] = simd_epi16; shift1[j] = simd_epi16;
shift1[j+1] = simd_epi16 >> 8; shift1[j + 1] = simd_epi16 >> 8;
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
shift1[j] = shift1[j] + 1; shift1[j] = shift1[j] + 1;
} }
for (j = 0, k = 0; j < 16; j += 2, k++) { for (j = 0, k = 0; j < 16; j += 2, k++) {
metric1[(2*i*16) + j] = survivor0[k]; metric1[(2 * i * 16) + j] = survivor0[k];
metric1[(2*i*16) + (j+1)] = survivor1[k]; metric1[(2 * i * 16) + (j + 1)] = survivor1[k];
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]);
} }
for (j = 0, k = 8; j < 16; j += 2, k++) { for (j = 0, k = 8; j < 16; j += 2, k++) {
metric1[((2*i+1)*16) + j] = survivor0[k]; metric1[((2 * i + 1) * 16) + j] = survivor0[k];
metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k];
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]);
} }
for (j = 0, k = 0; j < 16; j += 2, k++) { for (j = 0, k = 0; j < 16; j += 2, k++) {
path1[(2*i*16) + j] = tmp0[k]; path1[(2 * i * 16) + j] = tmp0[k];
path1[(2*i*16) + (j+1)] = tmp1[k]; path1[(2 * i * 16) + (j + 1)] = tmp1[k];
} }
for (j = 0, k = 8; j < 16; j += 2, k++) { for (j = 0, k = 8; j < 16; j += 2, k++) {
path1[((2*i+1)*16) + j] = tmp0[k]; path1[((2 * i + 1) * 16) + j] = tmp0[k];
path1[((2*i+1)*16) + (j+1)] = tmp1[k]; path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k];
} }
} }
@@ -202,28 +204,27 @@ viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (symbols[2] == 2) { if (symbols[2] == 2) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; metsvm[j] = d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j];
metsv[j] = 1 - metsvm[j]; metsv[j] = 1 - metsvm[j];
} }
} } else if (symbols[3] == 2) {
else if (symbols[3] == 2) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; metsvm[j] = d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j];
metsv[j] = 1 - metsvm[j]; metsv[j] = 1 - metsvm[j];
} }
} } else {
else {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); metsvm[j] = (d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]) +
(d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]);
metsv[j] = 2 - metsvm[j]; metsv[j] = 2 - metsvm[j];
} }
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
m0[j] = metric0[(i*16) + j] + metsv[j]; m0[j] = metric0[(i * 16) + j] + metsv[j];
m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j];
m2[j] = metric0[(i*16) + j] + metsvm[j]; m2[j] = metric0[(i * 16) + j] + metsvm[j];
m3[j] = metric0[((i+2)*16) + j] + metsv[j]; m3[j] = metric0[((i + 2) * 16) + j] + metsv[j];
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
@@ -234,53 +235,55 @@ viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols,
} }
for (j = 0; j < 16; j += 2) { for (j = 0; j < 16; j += 2) {
simd_epi16 = path0[(i*16) + j]; simd_epi16 = path0[(i * 16) + j];
simd_epi16 |= path0[(i*16) + (j+1)] << 8; simd_epi16 |= path0[(i * 16) + (j + 1)] << 8;
simd_epi16 <<= 1; simd_epi16 <<= 1;
shift0[j] = simd_epi16; shift0[j] = simd_epi16;
shift0[j+1] = simd_epi16 >> 8; shift0[j + 1] = simd_epi16 >> 8;
simd_epi16 = path0[((i+2)*16) + j]; simd_epi16 = path0[((i + 2) * 16) + j];
simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8;
simd_epi16 <<= 1; simd_epi16 <<= 1;
shift1[j] = simd_epi16; shift1[j] = simd_epi16;
shift1[j+1] = simd_epi16 >> 8; shift1[j + 1] = simd_epi16 >> 8;
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
shift1[j] = shift1[j] + 1; shift1[j] = shift1[j] + 1;
} }
for (j = 0, k = 0; j < 16; j += 2, k++) { for (j = 0, k = 0; j < 16; j += 2, k++) {
metric1[(2*i*16) + j] = survivor0[k]; metric1[(2 * i * 16) + j] = survivor0[k];
metric1[(2*i*16) + (j+1)] = survivor1[k]; metric1[(2 * i * 16) + (j + 1)] = survivor1[k];
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]);
} }
for (j = 0, k = 8; j < 16; j += 2, k++) { for (j = 0, k = 8; j < 16; j += 2, k++) {
metric1[((2*i+1)*16) + j] = survivor0[k]; metric1[((2 * i + 1) * 16) + j] = survivor0[k];
metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k];
} }
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]);
} }
for (j = 0, k = 0; j < 16; j += 2, k++) { for (j = 0, k = 0; j < 16; j += 2, k++) {
path1[(2*i*16) + j] = tmp0[k]; path1[(2 * i * 16) + j] = tmp0[k];
path1[(2*i*16) + (j+1)] = tmp1[k]; path1[(2 * i * 16) + (j + 1)] = tmp1[k];
} }
for (j = 0, k = 8; j < 16; j += 2, k++) { for (j = 0, k = 8; j < 16; j += 2, k++) {
path1[((2*i+1)*16) + j] = tmp0[k]; path1[((2 * i + 1) * 16) + j] = tmp0[k];
path1[((2*i+1)*16) + (j+1)] = tmp1[k]; path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k];
} }
} }
} }
// Find current best path // Find current best path
unsigned char unsigned char viterbi_decoder::viterbi_get_output_generic(unsigned char* mm0,
viterbi_decoder::viterbi_get_output_generic(unsigned char *mm0, unsigned char* pp0,
unsigned char *pp0, int ntraceback, unsigned char *outbuf) { int ntraceback,
unsigned char* outbuf)
{
int i; int i;
int bestmetric, minmetric; int bestmetric, minmetric;
int beststate = 0; int beststate = 0;
@@ -292,8 +295,8 @@ viterbi_decoder::viterbi_get_output_generic(unsigned char *mm0,
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
d_mmresult[(i*16) + j] = mm0[(i*16) + j]; d_mmresult[(i * 16) + j] = mm0[(i * 16) + j];
d_ppresult[d_store_pos][(i*16) + j] = pp0[(i*16) + j]; d_ppresult[d_store_pos][(i * 16) + j] = pp0[(i * 16) + j];
} }
} }
@@ -325,41 +328,46 @@ viterbi_decoder::viterbi_get_output_generic(unsigned char *mm0,
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
pp0[(i*16) + j] = 0; pp0[(i * 16) + j] = 0;
mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric; mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric;
} }
} }
return bestmetric; return bestmetric;
} }
uint8_t* uint8_t* viterbi_decoder::decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in)
viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) { {
d_ofdm = ofdm; d_ofdm = ofdm;
d_frame = frame; d_frame = frame;
reset(); reset();
uint8_t *depunctured = depuncture(in); uint8_t* depunctured = depuncture(in);
int in_count = 0; int in_count = 0;
int out_count = 0; int out_count = 0;
int n_decoded = 0; int n_decoded = 0;
while(n_decoded < d_frame->n_data_bits) { while (n_decoded < d_frame->n_data_bits) {
if ((in_count % 4) == 0) { //0 or 3 if ((in_count % 4) == 0) { // 0 or 3
viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], d_metric0_generic, d_metric1_generic, viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc],
d_path0_generic, d_path1_generic); d_metric0_generic,
d_metric1_generic,
d_path0_generic,
d_path1_generic);
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
unsigned char c; unsigned char c;
viterbi_get_output_generic(d_metric0_generic, d_path0_generic, d_ntraceback, &c); viterbi_get_output_generic(
d_metric0_generic, d_path0_generic, d_ntraceback, &c);
if (out_count >= d_ntraceback) { if (out_count >= d_ntraceback) {
for (int i= 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
d_decoded[(out_count - d_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; d_decoded[(out_count - d_ntraceback) * 8 + i] =
(c >> (7 - i)) & 0x1;
n_decoded++; n_decoded++;
} }
} }
@@ -372,12 +380,12 @@ viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) {
return d_decoded; return d_decoded;
} }
void void viterbi_decoder::reset()
viterbi_decoder::reset() { {
viterbi_chunks_init_generic(); viterbi_chunks_init_generic();
switch(d_ofdm->encoding) { switch (d_ofdm->encoding) {
case BPSK_1_2: case BPSK_1_2:
case QPSK_1_2: case QPSK_1_2:
case QAM16_1_2: case QAM16_1_2:
@@ -402,8 +410,8 @@ viterbi_decoder::reset() {
} }
// Initialize starting metrics to prefer 0 state // Initialize starting metrics to prefer 0 state
void void viterbi_decoder::viterbi_chunks_init_generic()
viterbi_decoder::viterbi_chunks_init_generic() { {
int i, j; int i, j;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@@ -412,9 +420,11 @@ viterbi_decoder::viterbi_chunks_init_generic() {
} }
int polys[2] = { 0x6d, 0x4f }; int polys[2] = { 0x6d, 0x4f };
for(i=0; i < 32; i++) { for (i = 0; i < 32; i++) {
d_branchtab27_generic[0].c[i] = (polys[0] < 0) ^ PARTAB[(2*i) & abs(polys[0])] ? 1 : 0; d_branchtab27_generic[0].c[i] =
d_branchtab27_generic[1].c[i] = (polys[1] < 0) ^ PARTAB[(2*i) & abs(polys[1])] ? 1 : 0; (polys[0] < 0) ^ PARTAB[(2 * i) & abs(polys[0])] ? 1 : 0;
d_branchtab27_generic[1].c[i] =
(polys[1] < 0) ^ PARTAB[(2 * i) & abs(polys[1])] ? 1 : 0;
} }
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
+13 -11
View File
@@ -30,28 +30,30 @@ namespace ieee802_11 {
class viterbi_decoder : public base class viterbi_decoder : public base
{ {
public: public:
virtual uint8_t* decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in);
virtual uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in);
private: private:
union branchtab27 { union branchtab27 {
unsigned char c[32]; unsigned char c[32];
} d_branchtab27_generic[2]; } d_branchtab27_generic[2];
unsigned char d_metric0_generic[64] __attribute__ ((aligned(16))); unsigned char d_metric0_generic[64] __attribute__((aligned(16)));
unsigned char d_metric1_generic[64] __attribute__ ((aligned(16))); unsigned char d_metric1_generic[64] __attribute__((aligned(16)));
unsigned char d_path0_generic[64] __attribute__ ((aligned(16))); unsigned char d_path0_generic[64] __attribute__((aligned(16)));
unsigned char d_path1_generic[64] __attribute__ ((aligned(16))); unsigned char d_path1_generic[64] __attribute__((aligned(16)));
void reset(); void reset();
void viterbi_chunks_init_generic(); void viterbi_chunks_init_generic();
void viterbi_butterfly2_generic(unsigned char *symbols, void viterbi_butterfly2_generic(unsigned char* symbols,
unsigned char m0[], unsigned char m1[], unsigned char p0[], unsigned char m0[],
unsigned char m1[],
unsigned char p0[],
unsigned char p1[]); unsigned char p1[]);
unsigned char viterbi_get_output_generic(unsigned char *mm0, unsigned char viterbi_get_output_generic(unsigned char* mm0,
unsigned char *pp0, int ntraceback, unsigned char *outbuf); unsigned char* pp0,
int ntraceback,
unsigned char* outbuf);
}; };
} // namespace ieee802_11 } // namespace ieee802_11
+96 -76
View File
@@ -56,35 +56,36 @@
* would spill over into memory. * would spill over into memory.
*/ */
#define BUTTERFLY(i,sym) { \ #define BUTTERFLY(i, sym) \
int m0,m1,m2,m3; \ { \
int m0, m1, m2, m3; \
/* ACS for 0 branch */ \ /* ACS for 0 branch */ \
m0 = state[i].metric + mets[sym]; /* 2*i */ \ m0 = state[i].metric + mets[sym]; /* 2*i */ \
m1 = state[i+32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \ m1 = state[i + 32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
if(m0 > m1){ \ if (m0 > m1) { \
next[2*i].metric = m0; \ next[2 * i].metric = m0; \
next[2*i].path = state[i].path << 1; \ next[2 * i].path = state[i].path << 1; \
} else { \ } else { \
next[2*i].metric = m1; \ next[2 * i].metric = m1; \
next[2*i].path = (state[i+32].path << 1)|1; \ next[2 * i].path = (state[i + 32].path << 1) | 1; \
} \ } \
/* ACS for 1 branch */ \ /* ACS for 1 branch */ \
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \ m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
m3 = state[i+32].metric + mets[sym]; /* 2*i + 65 */ \ m3 = state[i + 32].metric + mets[sym]; /* 2*i + 65 */ \
if(m2 > m3){ \ if (m2 > m3) { \
next[2*i+1].metric = m2; \ next[2 * i + 1].metric = m2; \
next[2*i+1].path = state[i].path << 1; \ next[2 * i + 1].path = state[i].path << 1; \
} else { \ } else { \
next[2*i+1].metric = m3; \ next[2 * i + 1].metric = m3; \
next[2*i+1].path = (state[i+32].path << 1)|1; \ next[2 * i + 1].path = (state[i + 32].path << 1) | 1; \
} \ } \
} }
using namespace gr::ieee802_11; using namespace gr::ieee802_11;
void void viterbi_decoder::viterbi_butterfly2_sse2(
viterbi_decoder::viterbi_butterfly2_sse2(unsigned char *symbols, unsigned char* symbols, __m128i* mm0, __m128i* mm1, __m128i* pp0, __m128i* pp1)
__m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1) { {
int i; int i;
__m128i *metric0, *metric1; __m128i *metric0, *metric1;
@@ -108,38 +109,43 @@ viterbi_decoder::viterbi_butterfly2_sse2(unsigned char *symbols,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (symbols[0] == 2) { if (symbols[0] == 2) {
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v); metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v);
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
} else if (symbols[1] == 2) { } else if (symbols[1] == 2) {
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v); metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v);
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
} else { } else {
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v)); metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v),
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm); _mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v));
metsv = _mm_sub_epi8(_mm_set1_epi8(2), metsvm);
} }
m0 = _mm_add_epi8(metric0[i], metsv); m0 = _mm_add_epi8(metric0[i], metsv);
m1 = _mm_add_epi8(metric0[i+2], metsvm); m1 = _mm_add_epi8(metric0[i + 2], metsvm);
m2 = _mm_add_epi8(metric0[i], metsvm); m2 = _mm_add_epi8(metric0[i], metsvm);
m3 = _mm_add_epi8(metric0[i+2], metsv); m3 = _mm_add_epi8(metric0[i + 2], metsv);
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128()); decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0, m1), _mm_setzero_si128());
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_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)); survivor0 =
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3)); _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); shift0 = _mm_slli_epi16(path0[i], 1);
shift1 = _mm_slli_epi16(path0[2+i], 1); shift1 = _mm_slli_epi16(path0[2 + i], 1);
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1)); shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1); metric1[2 * i] = _mm_unpacklo_epi8(survivor0, survivor1);
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1)); tmp0 = _mm_or_si128(_mm_and_si128(decision0, shift0),
_mm_andnot_si128(decision0, shift1));
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1); metric1[2 * i + 1] = _mm_unpackhi_epi8(survivor0, survivor1);
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1)); 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] = _mm_unpacklo_epi8(tmp0, tmp1);
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1); path1[2 * i + 1] = _mm_unpackhi_epi8(tmp0, tmp1);
} }
metric0 = mm1; metric0 = mm1;
@@ -152,47 +158,54 @@ viterbi_decoder::viterbi_butterfly2_sse2(unsigned char *symbols,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (symbols[2] == 2) { if (symbols[2] == 2) {
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v); metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v);
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
} else if (symbols[3] == 2) { } else if (symbols[3] == 2) {
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v); metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v);
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
} else { } else {
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v)); metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v),
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm); _mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v));
metsv = _mm_sub_epi8(_mm_set1_epi8(2), metsvm);
} }
m0 = _mm_add_epi8(metric0[i], metsv); m0 = _mm_add_epi8(metric0[i], metsv);
m1 = _mm_add_epi8(metric0[i+2], metsvm); m1 = _mm_add_epi8(metric0[i + 2], metsvm);
m2 = _mm_add_epi8(metric0[i], metsvm); m2 = _mm_add_epi8(metric0[i], metsvm);
m3 = _mm_add_epi8(metric0[i+2], metsv); m3 = _mm_add_epi8(metric0[i + 2], metsv);
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128()); decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0, m1), _mm_setzero_si128());
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_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)); survivor0 =
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3)); _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); shift0 = _mm_slli_epi16(path0[i], 1);
shift1 = _mm_slli_epi16(path0[2+i], 1); shift1 = _mm_slli_epi16(path0[2 + i], 1);
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1)); shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1); metric1[2 * i] = _mm_unpacklo_epi8(survivor0, survivor1);
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1)); tmp0 = _mm_or_si128(_mm_and_si128(decision0, shift0),
_mm_andnot_si128(decision0, shift1));
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1); metric1[2 * i + 1] = _mm_unpackhi_epi8(survivor0, survivor1);
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1)); 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] = _mm_unpacklo_epi8(tmp0, tmp1);
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1); path1[2 * i + 1] = _mm_unpackhi_epi8(tmp0, tmp1);
} }
} }
// Find current best path // Find current best path
unsigned char unsigned char viterbi_decoder::viterbi_get_output_sse2(__m128i* mm0,
viterbi_decoder::viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0, __m128i* pp0,
int ntraceback, unsigned char *outbuf) { int ntraceback,
unsigned char* outbuf)
{
int i; int i;
int bestmetric, minmetric; int bestmetric, minmetric;
int beststate = 0; int beststate = 0;
@@ -202,8 +215,8 @@ viterbi_decoder::viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0,
d_store_pos = (d_store_pos + 1) % ntraceback; d_store_pos = (d_store_pos + 1) % ntraceback;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
_mm_store_si128((__m128i *) &d_mmresult[i*16], mm0[i]); _mm_store_si128((__m128i*)&d_mmresult[i * 16], mm0[i]);
_mm_store_si128((__m128i *) &d_ppresult[d_store_pos][i*16], pp0[i]); _mm_store_si128((__m128i*)&d_ppresult[d_store_pos][i * 16], pp0[i]);
} }
// Find out the best final state // Find out the best final state
@@ -243,23 +256,27 @@ viterbi_decoder::viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0,
} }
uint8_t* uint8_t* viterbi_decoder::decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in)
viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) { {
d_ofdm = ofdm; d_ofdm = ofdm;
d_frame = frame; d_frame = frame;
reset(); reset();
uint8_t *depunctured = depuncture(in); uint8_t* depunctured = depuncture(in);
int in_count = 0; int in_count = 0;
int out_count = 0; int out_count = 0;
int n_decoded = 0; int n_decoded = 0;
while(n_decoded < d_frame->n_data_bits) { while (n_decoded < d_frame->n_data_bits) {
if ((in_count % 4) == 0) { //0 or 3 if ((in_count % 4) == 0) { // 0 or 3
viterbi_butterfly2_sse2(&depunctured[in_count & 0xfffffffc], d_metric0, d_metric1, d_path0, d_path1); viterbi_butterfly2_sse2(&depunctured[in_count & 0xfffffffc],
d_metric0,
d_metric1,
d_path0,
d_path1);
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
unsigned char c; unsigned char c;
@@ -267,8 +284,9 @@ viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) {
viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, &c); viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, &c);
if (out_count >= d_ntraceback) { if (out_count >= d_ntraceback) {
for (int i= 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
d_decoded[(out_count - d_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; d_decoded[(out_count - d_ntraceback) * 8 + i] =
(c >> (7 - i)) & 0x1;
n_decoded++; n_decoded++;
} }
} }
@@ -281,12 +299,12 @@ viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) {
return d_decoded; return d_decoded;
} }
void void viterbi_decoder::reset()
viterbi_decoder::reset() { {
viterbi_chunks_init_sse2(); viterbi_chunks_init_sse2();
switch(d_ofdm->encoding) { switch (d_ofdm->encoding) {
case BPSK_1_2: case BPSK_1_2:
case QPSK_1_2: case QPSK_1_2:
case QAM16_1_2: case QAM16_1_2:
@@ -311,8 +329,8 @@ viterbi_decoder::reset() {
} }
// Initialize starting metrics to prefer 0 state // Initialize starting metrics to prefer 0 state
void void viterbi_decoder::viterbi_chunks_init_sse2()
viterbi_decoder::viterbi_chunks_init_sse2() { {
int i, j; int i, j;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@@ -321,9 +339,11 @@ viterbi_decoder::viterbi_chunks_init_sse2() {
} }
int polys[2] = { 0x6d, 0x4f }; int polys[2] = { 0x6d, 0x4f };
for(i=0; i < 32; i++) { for (i = 0; i < 32; i++) {
d_branchtab27_sse2[0].c[i] = (polys[0] < 0) ^ PARTAB[(2*i) & abs(polys[0])] ? 1 : 0; d_branchtab27_sse2[0].c[i] =
d_branchtab27_sse2[1].c[i] = (polys[1] < 0) ^ PARTAB[(2*i) & abs(polys[1])] ? 1 : 0; (polys[0] < 0) ^ PARTAB[(2 * i) & abs(polys[0])] ? 1 : 0;
d_branchtab27_sse2[1].c[i] =
(polys[1] < 0) ^ PARTAB[(2 * i) & abs(polys[1])] ? 1 : 0;
} }
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
+12 -12
View File
@@ -17,8 +17,8 @@
#ifndef INCLUDED_IEEE802_11_VITERBI_DECODER_X86_H #ifndef INCLUDED_IEEE802_11_VITERBI_DECODER_X86_H
#define INCLUDED_IEEE802_11_VITERBI_DECODER_X86_H #define INCLUDED_IEEE802_11_VITERBI_DECODER_X86_H
#include <xmmintrin.h>
#include "base.h" #include "base.h"
#include <xmmintrin.h>
namespace gr { namespace gr {
namespace ieee802_11 { namespace ieee802_11 {
@@ -31,28 +31,28 @@ namespace ieee802_11 {
class viterbi_decoder : public base class viterbi_decoder : public base
{ {
public: public:
virtual uint8_t* decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in);
virtual uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in);
private: private:
union branchtab27 { union branchtab27 {
unsigned char c[32]; unsigned char c[32];
__m128i v[2]; __m128i v[2];
} d_branchtab27_sse2[2]; } d_branchtab27_sse2[2];
__m128i d_metric0[4] __attribute__ ((aligned(16))); __m128i d_metric0[4] __attribute__((aligned(16)));
__m128i d_metric1[4] __attribute__ ((aligned(16))); __m128i d_metric1[4] __attribute__((aligned(16)));
__m128i d_path0[4] __attribute__ ((aligned(16))); __m128i d_path0[4] __attribute__((aligned(16)));
__m128i d_path1[4] __attribute__ ((aligned(16))); __m128i d_path1[4] __attribute__((aligned(16)));
virtual void reset(); virtual void reset();
void viterbi_chunks_init_sse2(); void viterbi_chunks_init_sse2();
void viterbi_butterfly2_sse2(unsigned char *symbols, void viterbi_butterfly2_sse2(
__m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]); unsigned char* symbols, __m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
unsigned char viterbi_get_output_sse2(__m128i *mm0, unsigned char viterbi_get_output_sse2(__m128i* mm0,
__m128i *pp0, int ntraceback, unsigned char *outbuf); __m128i* pp0,
int ntraceback,
unsigned char* outbuf);
}; };
} // namespace ieee802_11 } // namespace ieee802_11