kopia lustrzana https://github.com/proto17/dji_droneid
Added demodulation, lte_decode, and decode modules
rodzic
94297ff21c
commit
a344cfddfb
|
@ -7,5 +7,6 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
droneid_decode.block.yml DESTINATION share/gnuradio/grc/blocks
|
droneid_decode.block.yml
|
||||||
|
droneid_demodulation.block.yml DESTINATION share/gnuradio/grc/blocks
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
id: droneid_demodulation
|
||||||
|
label: demodulation
|
||||||
|
category: '[droneid]'
|
||||||
|
|
||||||
|
templates:
|
||||||
|
imports: from gnuradio import droneid
|
||||||
|
make: droneid.demodulation(${sample_rate}, ${debug_path})
|
||||||
|
|
||||||
|
# Make one 'parameters' list entry for every parameter you want settable from the GUI.
|
||||||
|
# Keys include:
|
||||||
|
# * id (makes the value accessible as keyname, e.g. in the make entry)
|
||||||
|
# * label (label shown in the GUI)
|
||||||
|
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
|
||||||
|
# * default
|
||||||
|
parameters:
|
||||||
|
- id: sample_rate
|
||||||
|
label: Sample Rate
|
||||||
|
dtype: float
|
||||||
|
- id: debug_path
|
||||||
|
label: Debug path
|
||||||
|
dtype: string
|
||||||
|
|
||||||
|
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
|
||||||
|
# Keys include:
|
||||||
|
# * label (an identifier for the GUI)
|
||||||
|
# * domain (optional - stream or message. Default is stream)
|
||||||
|
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
|
||||||
|
# * vlen (optional - data stream vector length. Default is 1)
|
||||||
|
# * optional (optional - set to 1 for optional inputs. Default is 0)
|
||||||
|
inputs:
|
||||||
|
- label: pdus
|
||||||
|
domain: message
|
||||||
|
optional: 0
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
- label: pdus
|
||||||
|
domain: message
|
||||||
|
optional: 1
|
||||||
|
|
||||||
|
# 'file_format' specifies the version of the GRC yml format used in the file
|
||||||
|
# and should usually not be changed.
|
||||||
|
file_format: 1
|
|
@ -12,5 +12,7 @@
|
||||||
install(FILES
|
install(FILES
|
||||||
api.h
|
api.h
|
||||||
misc_utils.h
|
misc_utils.h
|
||||||
decode.h DESTINATION include/gnuradio/droneid
|
decode.h
|
||||||
|
demodulation.h
|
||||||
|
lte_decode.h DESTINATION include/gnuradio/droneid
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gr-droneid author.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_DRONEID_DEMODULATION_H
|
||||||
|
#define INCLUDED_DRONEID_DEMODULATION_H
|
||||||
|
|
||||||
|
#include <gnuradio/droneid/api.h>
|
||||||
|
#include <gnuradio/sync_block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace droneid {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief <+description of block+>
|
||||||
|
* \ingroup droneid
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DRONEID_API demodulation : virtual public gr::sync_block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::shared_ptr<demodulation> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of droneid::demodulation.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, droneid::demodulation's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. droneid::demodulation::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
static sptr make(double sample_rate, const std::string & debug_path);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace droneid
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_DRONEID_DEMODULATION_H */
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gr-droneid author.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_DRONEID_LTE_DECODE_H
|
||||||
|
#define INCLUDED_DRONEID_LTE_DECODE_H
|
||||||
|
|
||||||
|
#include <gnuradio/droneid/api.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <turbofec/rate_match.h>
|
||||||
|
#include <turbofec/turbo.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This line is required before the include of CRC.h so that it actually loads the CRC_24_LTEA definition
|
||||||
|
#define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS
|
||||||
|
#include <CRC.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace droneid {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief <+description+>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DRONEID_API lte_decode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
static constexpr uint32_t TURBO_ITERATIONS = 4;
|
||||||
|
static constexpr uint32_t TURBO_DECODER_BIT_COUNT = 1412;
|
||||||
|
static constexpr uint32_t TURBO_DECODER_INPUT_BIT_COUNT = 7200;
|
||||||
|
static constexpr uint32_t EXPECTED_PAYLOAD_BYTES = 176;
|
||||||
|
static constexpr uint32_t EXPECTED_PAYLOAD_BITS = EXPECTED_PAYLOAD_BYTES * 8;
|
||||||
|
|
||||||
|
std::vector<int8_t> d1_, d2_, d3_;
|
||||||
|
std::vector<int8_t> turbo_decoder_input_;
|
||||||
|
std::vector<uint8_t> decoded_bytes_;
|
||||||
|
|
||||||
|
struct lte_rate_matcher * rate_matcher_ = nullptr;
|
||||||
|
struct tdecoder * turbo_decoder_ = nullptr;
|
||||||
|
struct lte_rate_matcher_io rate_matcher_io_;
|
||||||
|
public:
|
||||||
|
lte_decode();
|
||||||
|
~lte_decode();
|
||||||
|
|
||||||
|
std::vector<uint8_t> decode(const std::vector<int8_t> & bits);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace droneid
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_DRONEID_LTE_DECODE_H */
|
|
@ -14,6 +14,8 @@ include(GrPlatform) #define LIB_SUFFIX
|
||||||
list(APPEND droneid_sources
|
list(APPEND droneid_sources
|
||||||
misc_utils.cc
|
misc_utils.cc
|
||||||
decode_impl.cc
|
decode_impl.cc
|
||||||
|
demodulation_impl.cc
|
||||||
|
lte_decode.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(droneid_sources "${droneid_sources}" PARENT_SCOPE)
|
set(droneid_sources "${droneid_sources}" PARENT_SCOPE)
|
||||||
|
@ -58,6 +60,7 @@ include(GrTest)
|
||||||
#include_directories()
|
#include_directories()
|
||||||
# List all files that contain Boost.UTF unit tests here
|
# List all files that contain Boost.UTF unit tests here
|
||||||
list(APPEND test_droneid_sources
|
list(APPEND test_droneid_sources
|
||||||
|
qa_demodulation.cc
|
||||||
qa_decode.cc
|
qa_decode.cc
|
||||||
)
|
)
|
||||||
# Anything we need to link to for the unit tests go here
|
# Anything we need to link to for the unit tests go here
|
||||||
|
|
|
@ -0,0 +1,479 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gr-droneid author.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "demodulation_impl.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <gnuradio/droneid/misc_utils.h>
|
||||||
|
#include <volk/volk.h>
|
||||||
|
#include <gnuradio/fft/fft.h>
|
||||||
|
#include <gnuradio/fft/fft_shift.h>
|
||||||
|
#include <numeric>
|
||||||
|
#include <gnuradio/droneid/lte_decode.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace droneid {
|
||||||
|
|
||||||
|
using path = boost::filesystem::path;
|
||||||
|
using utils = misc_utils;
|
||||||
|
|
||||||
|
demodulation::sptr
|
||||||
|
demodulation::make(double sample_rate, const std::string & debug_path) {
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new demodulation_impl(sample_rate, debug_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
demodulation_impl::demodulation_impl(const double sample_rate, const std::string & debug_path)
|
||||||
|
: gr::sync_block("demodulation",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
sample_rate_(sample_rate), fft_size_(misc_utils::get_fft_size(sample_rate)), long_cp_len_(
|
||||||
|
misc_utils::get_long_cp_len(sample_rate)), short_cp_len_(misc_utils::get_short_cp_len(sample_rate)),
|
||||||
|
debug_path_(debug_path){
|
||||||
|
if (! debug_path_.empty()) {
|
||||||
|
const auto p = path(debug_path_);
|
||||||
|
if (! boost::filesystem::is_directory(p)) {
|
||||||
|
boost::filesystem::create_directories(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("pdus"));
|
||||||
|
message_port_register_out(pmt::mp("pdus"));
|
||||||
|
set_msg_handler(pmt::mp("pdus"), [this](pmt::pmt_t pdu){handle_msg(pdu);});
|
||||||
|
cfo_cp_len_ = short_cp_len_;
|
||||||
|
burst_counter_ = 0;
|
||||||
|
cfo_buffer_.resize(cfo_cp_len_ * 2);
|
||||||
|
// sample_buffer_.resize((fft_size_ * 9) + (long_cp_len_ * 2) + (short_cp_len_ * 7));
|
||||||
|
|
||||||
|
cp_lengths_ = {
|
||||||
|
long_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
short_cp_len_,
|
||||||
|
long_cp_len_
|
||||||
|
};
|
||||||
|
|
||||||
|
symbols_.resize(cp_lengths_.size());
|
||||||
|
for (auto & vec : symbols_) {
|
||||||
|
vec.resize(fft_size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "FFT SIZE: " << fft_size_ << ", sample rate: " << sample_rate_ << "\n";
|
||||||
|
|
||||||
|
zc_ = misc_utils::create_zc_sequence(sample_rate_, 600);
|
||||||
|
fft_ = std::make_unique<gr::fft::fft_complex_fwd>(static_cast<int>(fft_size_), 1);
|
||||||
|
fft_shift_ = std::make_unique<gr::fft::fft_shift<std::complex<float>>>(fft_size_);
|
||||||
|
|
||||||
|
std::copy(zc_.begin(), zc_.end(), fft_->get_inbuf());
|
||||||
|
fft_->execute();
|
||||||
|
std::copy(fft_->get_outbuf(), fft_->get_outbuf() + fft_size_, zc_.begin());
|
||||||
|
std::for_each(zc_.begin(), zc_.end(), [this](std::complex<float> & sample){ sample /= static_cast<float>(fft_size_);});
|
||||||
|
fft_shift_->shift(zc_);
|
||||||
|
channel_.resize(fft_size_);
|
||||||
|
|
||||||
|
if (! debug_path_.empty()) {
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / "zc").string(), zc_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
demodulation_impl::~demodulation_impl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void demodulation_impl::handle_msg(pmt::pmt_t pdu) {
|
||||||
|
burst_counter_++;
|
||||||
|
|
||||||
|
const auto meta = pmt::car(pdu);
|
||||||
|
const auto vec = pmt::cdr(pdu);
|
||||||
|
const std::complex<float> I = {0, 1};
|
||||||
|
|
||||||
|
std::vector<std::complex<float>> samples(pmt::c32vector_elements(vec));
|
||||||
|
|
||||||
|
if (! debug_path_.empty()) {
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / ("burst_" + std::to_string(burst_counter_))).string(), samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample_buffer_.size() < samples.size()) {
|
||||||
|
sample_buffer_.resize(samples.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const auto start_idx_pmt = pmt::dict_ref(meta, pmt::mp("start_idx"), pmt::from_uint64(0));
|
||||||
|
const auto start_idx = pmt::to_uint64(start_idx_pmt);
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Find the ZC sequence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const auto zc_start_idx = utils::find_zc_seq_start_idx(samples, sample_rate_);
|
||||||
|
const auto est_start_index = zc_start_idx - (fft_size_ * 3) - long_cp_len_ - (short_cp_len_ * 3);
|
||||||
|
std::cout << "ZC start index: " << zc_start_idx << ", est start index: " << est_start_index << "\n";
|
||||||
|
|
||||||
|
const auto total_sample_count = est_start_index + (fft_size_ * 9) + (long_cp_len_ * 2) + (short_cp_len_ * 7);
|
||||||
|
if (est_start_index > samples.size() || total_sample_count > samples.size()) {
|
||||||
|
std::cout << "Did not receive enough samples! Skipping burst\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Coarse CFO estimate
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const auto cfo_backoff = 16;
|
||||||
|
const auto cfo_size = short_cp_len_ - (cfo_backoff * 2);
|
||||||
|
const std::vector<std::complex<float>> zc_seq_full_symbol(
|
||||||
|
&samples[zc_start_idx - short_cp_len_], &samples[zc_start_idx + fft_size_]);
|
||||||
|
const std::vector<std::complex<float>> cyclic_prefix(
|
||||||
|
zc_seq_full_symbol.begin() + cfo_backoff, zc_seq_full_symbol.begin() + cfo_backoff + cfo_size);
|
||||||
|
const std::vector<std::complex<float>> end_of_symbol(
|
||||||
|
zc_seq_full_symbol.end() - cfo_backoff - cfo_size, zc_seq_full_symbol.end() - cfo_backoff);
|
||||||
|
|
||||||
|
if (! debug_path_.empty()) {
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / ("received_zc_" + std::to_string(burst_counter_))).string(), zc_seq_full_symbol);
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / ("expected_zc_" + std::to_string(burst_counter_))).string(), zc_);
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / ("cfo_estimate_cyclic_prefix_" + std::to_string(burst_counter_))).string(), cyclic_prefix);
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / ("cfo_estimate_end_of_symbol_" + std::to_string(burst_counter_))).string(), end_of_symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::complex<float> cfo_dot_prod {0, 0};
|
||||||
|
for (uint32_t idx = 0; idx < cyclic_prefix.size(); idx++) {
|
||||||
|
cfo_dot_prod += cyclic_prefix[idx] * std::conj(end_of_symbol[idx]);
|
||||||
|
}
|
||||||
|
const auto cfo_angle = std::arg(cfo_dot_prod) / static_cast<float>(fft_size_);
|
||||||
|
const auto cfo_phase_angle = std::exp(I * -cfo_angle);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Coarse CFO correction
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::complex<float> starting_cfo_phase {1, 0};
|
||||||
|
volk_32fc_s32fc_x2_rotator_32fc(&samples[0], &samples[0], cfo_phase_angle, &starting_cfo_phase, samples.size());
|
||||||
|
|
||||||
|
if (! debug_path_.empty()) {
|
||||||
|
misc_utils::write_samples_vec((path(debug_path_) / ("burst_post_coarse_cfo_correction_" + std::to_string(burst_counter_))).string(), samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Channel estimation
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const auto symbols = utils::extract_ofdm_symbol_samples(samples, sample_rate_, est_start_index);
|
||||||
|
|
||||||
|
const auto zc_symbol_4_freq_domain = symbols[3].second;
|
||||||
|
const auto zc_symbol_6_freq_domain = symbols[5].second;
|
||||||
|
|
||||||
|
const auto zc_4_data_only = utils::extract_data_carriers(zc_symbol_4_freq_domain, fft_size_);
|
||||||
|
const auto zc_6_data_only = utils::extract_data_carriers(zc_symbol_6_freq_domain, fft_size_);
|
||||||
|
|
||||||
|
// utils::write_samples("/tmp/symbol_4", zc_4_data_only);
|
||||||
|
// utils::write_samples("/tmp/symbol_6", zc_6_data_only);
|
||||||
|
|
||||||
|
const auto zc_4_channel = utils::calculate_channel(zc_4_data_only, sample_rate_, 4);
|
||||||
|
const auto zc_6_channel = utils::calculate_channel(zc_6_data_only, sample_rate_, 6);
|
||||||
|
|
||||||
|
// utils::write_samples("/tmp/channel_4", zc_4_channel);
|
||||||
|
// utils::write_samples("/tmp/channel_6", zc_6_channel);
|
||||||
|
|
||||||
|
const auto zc_4_channel_angles = utils::angle(zc_4_channel);
|
||||||
|
const auto zc_6_channel_angles = utils::angle(zc_6_channel);
|
||||||
|
|
||||||
|
const auto zc_4_channel_phase = std::accumulate(zc_4_channel_angles.begin(), zc_4_channel_angles.end(), 0.0f) / 600;
|
||||||
|
const auto zc_6_channel_phase = std::accumulate(zc_6_channel_angles.begin(), zc_6_channel_angles.end(), 0.0f) / 600;
|
||||||
|
|
||||||
|
// std::cout << "4 phase: " << zc_4_channel_phase << "\n";
|
||||||
|
// std::cout << "6 phase: " << zc_6_channel_phase << "\n";
|
||||||
|
|
||||||
|
const auto channel_phase_adj = (zc_4_channel_phase - zc_6_channel_phase) / 2;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Save Constellation
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::vector<std::complex<float>> all_data_carriers;
|
||||||
|
for (int idx = 0; idx < 9; idx++) {
|
||||||
|
if (idx == 1 || idx == 3 || idx == 5) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto data_carriers = utils::extract_data_carriers(symbols[idx].second, fft_size_);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < 600; i++) {
|
||||||
|
data_carriers[i] *= zc_4_channel[i];
|
||||||
|
// data_carriers[i] *= std::exp(I * (-channel_phase_adj * static_cast<float>(idx - 6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
all_data_carriers.insert(all_data_carriers.end(), data_carriers.begin(), data_carriers.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
message_port_pub(pmt::mp("pdus"), pmt::cons(pmt::make_dict(), pmt::init_c32vector(all_data_carriers.size(), all_data_carriers)));
|
||||||
|
|
||||||
|
// utils::write_samples("/tmp/all_data", all_data_carriers);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// QPSK to bits
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
auto bits = utils::qpsk_to_bits(all_data_carriers);
|
||||||
|
|
||||||
|
for (int idx = 0; idx < 7200; idx++) {
|
||||||
|
if (bits[idx] == 1 && XOR_BIT_VEC[idx] == 1) {
|
||||||
|
bits[idx] = 0;
|
||||||
|
} else if (bits[idx] == 0 && XOR_BIT_VEC[idx] == 0) {
|
||||||
|
bits[idx] = 0;
|
||||||
|
} else {
|
||||||
|
bits[idx] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Setup and run the Turbo decoder
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const size_t input_file_bit_count = 7200;
|
||||||
|
|
||||||
|
const int turbo_iterations = 4;
|
||||||
|
const int turbo_decoder_bit_count = 1412; // Number of bits that the Turbo decoder will take in
|
||||||
|
const int expected_payload_bytes = 176; // Number of bytes that the Turbo decoder will output
|
||||||
|
const int expected_payload_bits = expected_payload_bytes * 8;
|
||||||
|
|
||||||
|
// Allocate buffers for the Turbo decoder
|
||||||
|
std::vector<int8_t> d1(turbo_decoder_bit_count);
|
||||||
|
std::vector<int8_t> d2(turbo_decoder_bit_count);
|
||||||
|
std::vector<int8_t> d3(turbo_decoder_bit_count);
|
||||||
|
std::vector<uint8_t> decoded_bytes(expected_payload_bytes);
|
||||||
|
|
||||||
|
// Create the required structures to run the Turbo decoder
|
||||||
|
struct lte_rate_matcher * rate_matcher = lte_rate_matcher_alloc();
|
||||||
|
struct tdecoder * turbo_decoder = alloc_tdec();
|
||||||
|
struct lte_rate_matcher_io rate_matcher_io = {
|
||||||
|
.D = turbo_decoder_bit_count,
|
||||||
|
.E = input_file_bit_count,
|
||||||
|
.d = {&d1[0], &d2[0], &d3[0]},
|
||||||
|
.e = &bits[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup the rate matching logic
|
||||||
|
lte_rate_match_rv(rate_matcher, &rate_matcher_io, 0);
|
||||||
|
|
||||||
|
// Run the turbo decoder (will do rate matching as well)
|
||||||
|
const int decode_status = lte_turbo_decode(turbo_decoder, expected_payload_bits, turbo_iterations,
|
||||||
|
&decoded_bytes[0], &d1[0], &d2[0], &d3[0]);
|
||||||
|
|
||||||
|
if (decode_status != 0) {
|
||||||
|
std::cerr << "Failed to decode\n";
|
||||||
|
} else {
|
||||||
|
for (const auto & b : decoded_bytes) {
|
||||||
|
fprintf(stdout, "%02x", b);
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
const auto crc_out = CRC::Calculate(&decoded_bytes[0], decoded_bytes.size(), CRC::CRC_24_LTEA());
|
||||||
|
if (crc_out != 0) {
|
||||||
|
std::cerr << "CRC Check Failed!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_tdec(turbo_decoder);
|
||||||
|
lte_rate_matcher_free(rate_matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
demodulation_impl::work(int noutput_items,
|
||||||
|
gr_vector_const_void_star &input_items,
|
||||||
|
gr_vector_void_star &output_items) {
|
||||||
|
// Do <+signal processing+>
|
||||||
|
|
||||||
|
// Tell runtime system how many output items we produced.
|
||||||
|
return noutput_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t demodulation_impl::XOR_BIT_VEC[7200] = {
|
||||||
|
1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1
|
||||||
|
, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0
|
||||||
|
, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0
|
||||||
|
, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0
|
||||||
|
, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0
|
||||||
|
, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0
|
||||||
|
, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0
|
||||||
|
, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0
|
||||||
|
, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0
|
||||||
|
, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1
|
||||||
|
, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1
|
||||||
|
, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1
|
||||||
|
, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
|
||||||
|
, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1
|
||||||
|
, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1
|
||||||
|
, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0
|
||||||
|
, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0
|
||||||
|
, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0
|
||||||
|
, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0
|
||||||
|
, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0
|
||||||
|
, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1
|
||||||
|
, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0
|
||||||
|
, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0
|
||||||
|
, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0
|
||||||
|
, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1
|
||||||
|
, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0
|
||||||
|
, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0
|
||||||
|
, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1
|
||||||
|
, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1
|
||||||
|
, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1
|
||||||
|
, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1
|
||||||
|
, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0
|
||||||
|
, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0
|
||||||
|
, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0
|
||||||
|
, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0
|
||||||
|
, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1
|
||||||
|
, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0
|
||||||
|
, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0
|
||||||
|
, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0
|
||||||
|
, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0
|
||||||
|
, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0
|
||||||
|
, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1
|
||||||
|
, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0
|
||||||
|
, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1
|
||||||
|
, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1
|
||||||
|
, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0
|
||||||
|
, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1
|
||||||
|
, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0
|
||||||
|
, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0
|
||||||
|
, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0
|
||||||
|
, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1
|
||||||
|
, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0
|
||||||
|
, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1
|
||||||
|
, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1
|
||||||
|
, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0
|
||||||
|
, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
|
||||||
|
, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1
|
||||||
|
, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0
|
||||||
|
, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0
|
||||||
|
, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0
|
||||||
|
, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0
|
||||||
|
, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0
|
||||||
|
, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1
|
||||||
|
, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1
|
||||||
|
, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0
|
||||||
|
, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1
|
||||||
|
, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0
|
||||||
|
, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1
|
||||||
|
, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1
|
||||||
|
, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1
|
||||||
|
, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
|
||||||
|
, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0
|
||||||
|
, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1
|
||||||
|
, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0
|
||||||
|
, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1
|
||||||
|
, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1
|
||||||
|
, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1
|
||||||
|
, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0
|
||||||
|
, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0
|
||||||
|
, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1
|
||||||
|
, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1
|
||||||
|
, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1
|
||||||
|
, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1
|
||||||
|
, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1
|
||||||
|
, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0
|
||||||
|
, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1
|
||||||
|
, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0
|
||||||
|
, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1
|
||||||
|
, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1
|
||||||
|
, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1
|
||||||
|
, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1
|
||||||
|
, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0
|
||||||
|
, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0
|
||||||
|
, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0
|
||||||
|
, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0
|
||||||
|
, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1
|
||||||
|
, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1
|
||||||
|
, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0
|
||||||
|
, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0
|
||||||
|
, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0
|
||||||
|
, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0
|
||||||
|
, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1
|
||||||
|
, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1
|
||||||
|
, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0
|
||||||
|
, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0
|
||||||
|
, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0
|
||||||
|
, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0
|
||||||
|
, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0
|
||||||
|
, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1
|
||||||
|
, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1
|
||||||
|
, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0
|
||||||
|
, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1
|
||||||
|
, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1
|
||||||
|
, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0
|
||||||
|
, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0
|
||||||
|
, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1
|
||||||
|
, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1
|
||||||
|
, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0
|
||||||
|
, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
||||||
|
, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1
|
||||||
|
, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1
|
||||||
|
, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0
|
||||||
|
, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1
|
||||||
|
, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
|
||||||
|
, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0
|
||||||
|
, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0
|
||||||
|
, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
|
||||||
|
, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1
|
||||||
|
, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0
|
||||||
|
, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0
|
||||||
|
, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0
|
||||||
|
, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1
|
||||||
|
, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0
|
||||||
|
, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1
|
||||||
|
, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0
|
||||||
|
, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1
|
||||||
|
, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1
|
||||||
|
, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0
|
||||||
|
, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1
|
||||||
|
, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1
|
||||||
|
, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1
|
||||||
|
, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1
|
||||||
|
, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1
|
||||||
|
, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1
|
||||||
|
, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0
|
||||||
|
, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1
|
||||||
|
, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1
|
||||||
|
, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0
|
||||||
|
, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
||||||
|
, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1
|
||||||
|
, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0
|
||||||
|
, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0
|
||||||
|
, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0
|
||||||
|
, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0
|
||||||
|
, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1
|
||||||
|
, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0
|
||||||
|
, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0
|
||||||
|
, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0
|
||||||
|
, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0
|
||||||
|
, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1
|
||||||
|
, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1
|
||||||
|
, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0
|
||||||
|
, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1
|
||||||
|
, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1
|
||||||
|
, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace droneid */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gr-droneid author.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_DRONEID_DEMODULATION_IMPL_H
|
||||||
|
#define INCLUDED_DRONEID_DEMODULATION_IMPL_H
|
||||||
|
|
||||||
|
#include <gnuradio/droneid/demodulation.h>
|
||||||
|
#include <gnuradio/fft/fft.h>
|
||||||
|
#include <gnuradio/fft/fft_shift.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace droneid {
|
||||||
|
|
||||||
|
class demodulation_impl : public demodulation {
|
||||||
|
private:
|
||||||
|
const double sample_rate_;
|
||||||
|
const uint32_t fft_size_;
|
||||||
|
const uint32_t long_cp_len_;
|
||||||
|
const uint32_t short_cp_len_;
|
||||||
|
const std::string debug_path_;
|
||||||
|
|
||||||
|
const static uint8_t XOR_BIT_VEC [7200];
|
||||||
|
|
||||||
|
std::unique_ptr<gr::fft::fft_complex_fwd> fft_;
|
||||||
|
std::unique_ptr<gr::fft::fft_shift<std::complex<float>>> fft_shift_;
|
||||||
|
uint32_t burst_counter_;
|
||||||
|
size_t sample_count_;
|
||||||
|
uint32_t cfo_cp_len_;
|
||||||
|
std::vector<uint32_t> cp_lengths_;
|
||||||
|
std::vector<std::complex<float>> zc_;
|
||||||
|
std::vector<std::complex<float>> channel_;
|
||||||
|
std::vector<std::vector<std::complex<float>>> symbols_;
|
||||||
|
std::vector<std::complex<float>> cfo_buffer_;
|
||||||
|
std::vector<std::complex<float>> sample_buffer_;
|
||||||
|
|
||||||
|
void handle_msg(pmt::pmt_t pdu);
|
||||||
|
// Nothing to declare in this block.
|
||||||
|
|
||||||
|
public:
|
||||||
|
demodulation_impl(double sample_rate, const std::string & debug_path);
|
||||||
|
|
||||||
|
~demodulation_impl();
|
||||||
|
|
||||||
|
// Where all the action really happens
|
||||||
|
int work(
|
||||||
|
int noutput_items,
|
||||||
|
gr_vector_const_void_star &input_items,
|
||||||
|
gr_vector_void_star &output_items
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace droneid
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_DRONEID_DEMODULATION_IMPL_H */
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gr-droneid author.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gnuradio/droneid/lte_decode.h>
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace droneid {
|
||||||
|
|
||||||
|
lte_decode::lte_decode() {
|
||||||
|
d1_.resize(TURBO_DECODER_BIT_COUNT);
|
||||||
|
d2_.resize(TURBO_DECODER_BIT_COUNT);
|
||||||
|
d3_.resize(TURBO_DECODER_BIT_COUNT);
|
||||||
|
|
||||||
|
turbo_decoder_input_.resize(TURBO_DECODER_INPUT_BIT_COUNT);
|
||||||
|
decoded_bytes_.resize(EXPECTED_PAYLOAD_BYTES);
|
||||||
|
|
||||||
|
rate_matcher_ = lte_rate_matcher_alloc();
|
||||||
|
turbo_decoder_ = alloc_tdec();
|
||||||
|
|
||||||
|
rate_matcher_io_ = {
|
||||||
|
.D = TURBO_DECODER_BIT_COUNT,
|
||||||
|
.E = TURBO_DECODER_INPUT_BIT_COUNT,
|
||||||
|
.d = {&d1_[0], &d2_[0], &d3_[0]},
|
||||||
|
.e = &turbo_decoder_input_[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
lte_decode::~lte_decode() {
|
||||||
|
if (rate_matcher_ != nullptr) {
|
||||||
|
lte_rate_matcher_free(rate_matcher_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turbo_decoder_ != nullptr) {
|
||||||
|
free_tdec(turbo_decoder_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> lte_decode::decode(const std::vector<int8_t> &bits) {
|
||||||
|
if (bits.size() != TURBO_DECODER_INPUT_BIT_COUNT) {
|
||||||
|
std::ostringstream err;
|
||||||
|
err << "Turbo decoder expected " << TURBO_DECODER_INPUT_BIT_COUNT << " but got " << bits.size();
|
||||||
|
throw std::runtime_error(err.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t bit_lut[2] = {-63, 63};
|
||||||
|
std::vector<int8_t> bits_copy = bits;
|
||||||
|
for (int idx = 0; idx < bits.size(); idx++) {
|
||||||
|
turbo_decoder_input_[idx] = bit_lut[bits[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
lte_rate_match_fw(rate_matcher_, &rate_matcher_io_, 0);
|
||||||
|
const int decode_status = lte_turbo_decode(turbo_decoder_, EXPECTED_PAYLOAD_BITS, TURBO_ITERATIONS,
|
||||||
|
&decoded_bytes_[0], &d1_[0], &d2_[0], &d3_[0]);
|
||||||
|
|
||||||
|
fprintf(stdout, "MOO: ");
|
||||||
|
for (const auto & i : decoded_bytes_) {
|
||||||
|
fprintf(stdout, "%02x", i);
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
if (decode_status != 0) {
|
||||||
|
throw std::runtime_error("Failed to remove Turbo code. Status: " + std::to_string(decode_status));
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t calculated_crc = CRC::Calculate(&decoded_bytes_[0], decoded_bytes_.size(), CRC::CRC_24_LTEA());
|
||||||
|
if (calculated_crc != 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoded_bytes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace droneid */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gr-droneid author.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gnuradio/attributes.h>
|
||||||
|
#include <gnuradio/droneid/demodulation.h>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace droneid {
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_demodulation_replace_with_specific_test_name)
|
||||||
|
{
|
||||||
|
// Put test here
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace droneid */
|
||||||
|
} /* namespace gr */
|
|
@ -30,7 +30,9 @@ include(GrPybind)
|
||||||
|
|
||||||
list(APPEND droneid_python_files
|
list(APPEND droneid_python_files
|
||||||
misc_utils_python.cc
|
misc_utils_python.cc
|
||||||
decode_python.cc python_bindings.cc)
|
decode_python.cc
|
||||||
|
demodulation_python.cc
|
||||||
|
lte_decode_python.cc python_bindings.cc)
|
||||||
|
|
||||||
GR_PYBIND_MAKE_OOT(droneid
|
GR_PYBIND_MAKE_OOT(droneid
|
||||||
../../..
|
../../..
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Radio
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***********************************************************************************/
|
||||||
|
/* This file is automatically generated using bindtool and can be manually edited */
|
||||||
|
/* The following lines can be configured to regenerate this file during cmake */
|
||||||
|
/* If manual edits are made, the following tags should be modified accordingly. */
|
||||||
|
/* BINDTOOL_GEN_AUTOMATIC(0) */
|
||||||
|
/* BINDTOOL_USE_PYGCCXML(0) */
|
||||||
|
/* BINDTOOL_HEADER_FILE(demodulation.h) */
|
||||||
|
/* BINDTOOL_HEADER_FILE_HASH(848192abf7e376e88031ffe617420115) */
|
||||||
|
/***********************************************************************************/
|
||||||
|
|
||||||
|
#include <pybind11/complex.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
#include <gnuradio/droneid/demodulation.h>
|
||||||
|
// pydoc.h is automatically generated in the build directory
|
||||||
|
#include <demodulation_pydoc.h>
|
||||||
|
|
||||||
|
void bind_demodulation(py::module& m)
|
||||||
|
{
|
||||||
|
|
||||||
|
using demodulation = ::gr::droneid::demodulation;
|
||||||
|
|
||||||
|
|
||||||
|
py::class_<demodulation,
|
||||||
|
gr::sync_block,
|
||||||
|
gr::block,
|
||||||
|
gr::basic_block,
|
||||||
|
std::shared_ptr<demodulation>>(m, "demodulation", D(demodulation))
|
||||||
|
|
||||||
|
.def(py::init(&demodulation::make),
|
||||||
|
py::arg("sample_rate"),
|
||||||
|
py::arg("debug_path"),
|
||||||
|
D(demodulation, make))
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Radio
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "pydoc_macros.h"
|
||||||
|
#define D(...) DOC(gr, droneid, __VA_ARGS__)
|
||||||
|
/*
|
||||||
|
This file contains placeholders for docstrings for the Python bindings.
|
||||||
|
Do not edit! These were automatically extracted during the binding process
|
||||||
|
and will be overwritten during the build process
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_demodulation = R"doc()doc";
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_demodulation_demodulation = R"doc()doc";
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_demodulation_make = R"doc()doc";
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Radio
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "pydoc_macros.h"
|
||||||
|
#define D(...) DOC(gr, droneid, __VA_ARGS__)
|
||||||
|
/*
|
||||||
|
This file contains placeholders for docstrings for the Python bindings.
|
||||||
|
Do not edit! These were automatically extracted during the binding process
|
||||||
|
and will be overwritten during the build process
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_lte_decode = R"doc()doc";
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_lte_decode_lte_decode_0 = R"doc()doc";
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_lte_decode_lte_decode_1 = R"doc()doc";
|
||||||
|
|
||||||
|
|
||||||
|
static const char* __doc_gr_droneid_lte_decode_decode = R"doc()doc";
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Radio
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***********************************************************************************/
|
||||||
|
/* This file is automatically generated using bindtool and can be manually edited */
|
||||||
|
/* The following lines can be configured to regenerate this file during cmake */
|
||||||
|
/* If manual edits are made, the following tags should be modified accordingly. */
|
||||||
|
/* BINDTOOL_GEN_AUTOMATIC(0) */
|
||||||
|
/* BINDTOOL_USE_PYGCCXML(0) */
|
||||||
|
/* BINDTOOL_HEADER_FILE(lte_decode.h) */
|
||||||
|
/* BINDTOOL_HEADER_FILE_HASH(ded435d307a83ab16445df9b219c865d) */
|
||||||
|
/***********************************************************************************/
|
||||||
|
|
||||||
|
#include <pybind11/complex.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
#include <gnuradio/droneid/lte_decode.h>
|
||||||
|
// pydoc.h is automatically generated in the build directory
|
||||||
|
#include <lte_decode_pydoc.h>
|
||||||
|
|
||||||
|
void bind_lte_decode(py::module& m)
|
||||||
|
{
|
||||||
|
|
||||||
|
using lte_decode = ::gr::droneid::lte_decode;
|
||||||
|
|
||||||
|
|
||||||
|
py::class_<lte_decode, std::shared_ptr<lte_decode>>(m, "lte_decode", D(lte_decode))
|
||||||
|
|
||||||
|
.def(py::init<>(), D(lte_decode, lte_decode, 0))
|
||||||
|
.def(py::init<gr::droneid::lte_decode const&>(),
|
||||||
|
py::arg("arg0"),
|
||||||
|
D(lte_decode, lte_decode, 1))
|
||||||
|
|
||||||
|
|
||||||
|
.def("decode", <e_decode::decode, py::arg("bits"), D(lte_decode, decode))
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ namespace py = pybind11;
|
||||||
// BINDING_FUNCTION_PROTOTYPES(
|
// BINDING_FUNCTION_PROTOTYPES(
|
||||||
void bind_misc_utils(py::module& m);
|
void bind_misc_utils(py::module& m);
|
||||||
void bind_decode(py::module& m);
|
void bind_decode(py::module& m);
|
||||||
|
void bind_demodulation(py::module& m);
|
||||||
|
void bind_lte_decode(py::module& m);
|
||||||
// ) END BINDING_FUNCTION_PROTOTYPES
|
// ) END BINDING_FUNCTION_PROTOTYPES
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,5 +57,7 @@ PYBIND11_MODULE(droneid_python, m)
|
||||||
// BINDING_FUNCTION_CALLS(
|
// BINDING_FUNCTION_CALLS(
|
||||||
bind_misc_utils(m);
|
bind_misc_utils(m);
|
||||||
bind_decode(m);
|
bind_decode(m);
|
||||||
|
bind_demodulation(m);
|
||||||
|
bind_lte_decode(m);
|
||||||
// ) END BINDING_FUNCTION_CALLS
|
// ) END BINDING_FUNCTION_CALLS
|
||||||
}
|
}
|
Ładowanie…
Reference in New Issue