mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 06:49:24 -05:00
Rework BitHistory, BitPattern, PacketBuilder.
Templatize PacketBuilder to optionally bit unstuff, and have flexible packet termination behavior.
This commit is contained in:
parent
0b522abbc1
commit
0789d50fdf
@ -20,18 +20,3 @@
|
||||
*/
|
||||
|
||||
#include "packet_builder.hpp"
|
||||
|
||||
void PacketBuilder::configure(
|
||||
const BitPattern preamble,
|
||||
const BitPattern unstuff
|
||||
) {
|
||||
preamble_pattern = preamble;
|
||||
unstuff_pattern = unstuff;
|
||||
|
||||
reset_state();
|
||||
}
|
||||
|
||||
void PacketBuilder::reset_state() {
|
||||
bits_received = 0;
|
||||
state = State::Preamble;
|
||||
}
|
||||
|
@ -29,21 +29,33 @@
|
||||
|
||||
#include "bit_pattern.hpp"
|
||||
|
||||
template<typename PreambleMatcher, typename UnstuffMatcher, typename EndMatcher>
|
||||
class PacketBuilder {
|
||||
public:
|
||||
using PayloadType = std::bitset<1024>;
|
||||
using PayloadHandlerFunc = std::function<void(const PayloadType& payload, const size_t bits_received)>;
|
||||
|
||||
PacketBuilder(
|
||||
const PreambleMatcher preamble_matcher,
|
||||
const UnstuffMatcher unstuff_matcher,
|
||||
const EndMatcher end_matcher,
|
||||
const PayloadHandlerFunc payload_handler
|
||||
) : payload_handler { payload_handler }
|
||||
) : payload_handler { payload_handler },
|
||||
preamble(preamble_matcher),
|
||||
unstuff(unstuff_matcher),
|
||||
end(end_matcher)
|
||||
{
|
||||
}
|
||||
|
||||
void configure(
|
||||
const BitPattern preamble,
|
||||
const BitPattern unstuffing
|
||||
);
|
||||
const PreambleMatcher preamble_matcher,
|
||||
const UnstuffMatcher unstuff_matcher
|
||||
) {
|
||||
preamble = preamble_matcher;
|
||||
unstuff = unstuff_matcher;
|
||||
|
||||
reset_state();
|
||||
}
|
||||
|
||||
void execute(
|
||||
const uint_fast8_t symbol
|
||||
@ -52,25 +64,24 @@ public:
|
||||
|
||||
switch(state) {
|
||||
case State::Preamble:
|
||||
if( found_preamble() ) {
|
||||
if( preamble(bit_history, bits_received) ) {
|
||||
state = State::Payload;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::Payload:
|
||||
if( !found_stuffing_bit() ) {
|
||||
if( !unstuff(bit_history, bits_received) ) {
|
||||
payload[bits_received++] = symbol;
|
||||
}
|
||||
|
||||
if( found_end_flag() ) {
|
||||
payload_handler(payload, bits_received - 7);
|
||||
if( end(bit_history, bits_received) ) {
|
||||
payload_handler(payload, bits_received);
|
||||
reset_state();
|
||||
} else {
|
||||
if( packet_truncated() ) {
|
||||
reset_state();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -89,30 +100,21 @@ private:
|
||||
return bits_received >= payload.size();
|
||||
}
|
||||
|
||||
bool found_preamble() const {
|
||||
return bit_history.matches(preamble_pattern);
|
||||
}
|
||||
|
||||
bool found_stuffing_bit() const {
|
||||
return bit_history.matches(unstuff_pattern);
|
||||
}
|
||||
|
||||
bool found_end_flag() const {
|
||||
return bit_history.matches(end_flag_pattern);
|
||||
}
|
||||
|
||||
const PayloadHandlerFunc payload_handler;
|
||||
|
||||
BitHistory bit_history;
|
||||
BitPattern preamble_pattern { 0b0101010101111110, 16, 1 };
|
||||
BitPattern unstuff_pattern { 0b111110, 6 };
|
||||
BitPattern end_flag_pattern { 0b01111110, 8 };
|
||||
PreambleMatcher preamble;
|
||||
UnstuffMatcher unstuff;
|
||||
EndMatcher end;
|
||||
|
||||
size_t bits_received { 0 };
|
||||
State state { State::Preamble };
|
||||
PayloadType payload;
|
||||
|
||||
void reset_state();
|
||||
void reset_state() {
|
||||
bits_received = 0;
|
||||
state = State::Preamble;
|
||||
}
|
||||
};
|
||||
|
||||
#endif/*__PACKET_BUILDER_H__*/
|
||||
|
@ -56,8 +56,11 @@ private:
|
||||
[this](const float symbol) { this->consume_symbol(symbol); }
|
||||
};
|
||||
symbol_coding::NRZIDecoder nrzi_decode;
|
||||
PacketBuilder packet_builder {
|
||||
[this](const PacketBuilder::PayloadType& payload, const size_t bits_received) {
|
||||
PacketBuilder<BitPattern, BitPattern, BitPattern> packet_builder {
|
||||
{ 0b0101010101111110, 16, 1 },
|
||||
{ 0b111110, 6 },
|
||||
{ 0b01111110, 8 },
|
||||
[this](const payload_t& payload, const size_t bits_received) {
|
||||
this->payload_handler(payload, bits_received);
|
||||
}
|
||||
};
|
||||
|
@ -299,7 +299,8 @@ static std::string ais_format_navigational_status(const unsigned int value) {
|
||||
decoded_packet packet_decode(const std::bitset<1024>& payload, const size_t payload_length) {
|
||||
// TODO: Unstuff here, not in baseband!
|
||||
|
||||
const size_t data_and_fcs_length = payload_length;
|
||||
// Subtract end flag (6 bits) + one unstuffing bit (occurs during end flag).
|
||||
const size_t data_and_fcs_length = payload_length - 7;
|
||||
|
||||
if( data_and_fcs_length < 38 ) {
|
||||
return { "short " + ui::to_string_dec_uint(data_and_fcs_length, 3), "" };
|
||||
|
@ -25,8 +25,29 @@
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
class BitHistory {
|
||||
public:
|
||||
void add(const uint_fast8_t bit) {
|
||||
history = (history << 1) | (bit & 1);
|
||||
}
|
||||
|
||||
uint32_t value() const {
|
||||
return history;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t history { 0 };
|
||||
};
|
||||
|
||||
class BitPattern {
|
||||
public:
|
||||
constexpr BitPattern(
|
||||
) : code_ { 0 },
|
||||
mask_ { 0 },
|
||||
maximum_hanning_distance_ { 0 }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr BitPattern(
|
||||
const uint32_t code,
|
||||
const size_t code_length,
|
||||
@ -37,16 +58,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t code() const {
|
||||
return code_;
|
||||
}
|
||||
|
||||
uint32_t mask() const {
|
||||
return mask_;
|
||||
}
|
||||
|
||||
size_t maximum_hanning_distance() const {
|
||||
return maximum_hanning_distance_;
|
||||
bool operator()(const BitHistory& history, const size_t) const {
|
||||
const auto delta_bits = (history.value() ^ code_) & mask_;
|
||||
const size_t count = __builtin_popcountl(delta_bits);
|
||||
return (count <= maximum_hanning_distance_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -55,20 +70,4 @@ private:
|
||||
size_t maximum_hanning_distance_;
|
||||
};
|
||||
|
||||
class BitHistory {
|
||||
public:
|
||||
void add(const uint_fast8_t bit) {
|
||||
history = (history << 1) | (bit & 1);
|
||||
}
|
||||
|
||||
bool matches(const BitPattern& pattern) const {
|
||||
const auto delta_bits = (history ^ pattern.code()) & pattern.mask();
|
||||
const size_t count = __builtin_popcountl(delta_bits);
|
||||
return (count <= pattern.maximum_hanning_distance());
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t history { 0 };
|
||||
};
|
||||
|
||||
#endif/*__BIT_PATTERN_H__*/
|
||||
|
Loading…
Reference in New Issue
Block a user