diff --git a/firmware/baseband/packet_builder.cpp b/firmware/baseband/packet_builder.cpp index f759707b1..0fa5ec201 100644 --- a/firmware/baseband/packet_builder.cpp +++ b/firmware/baseband/packet_builder.cpp @@ -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; -} diff --git a/firmware/baseband/packet_builder.hpp b/firmware/baseband/packet_builder.hpp index 13fa178f5..edf503579 100644 --- a/firmware/baseband/packet_builder.hpp +++ b/firmware/baseband/packet_builder.hpp @@ -29,21 +29,33 @@ #include "bit_pattern.hpp" +template class PacketBuilder { public: using PayloadType = std::bitset<1024>; using PayloadHandlerFunc = std::function; 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__*/ diff --git a/firmware/baseband/proc_fsk.hpp b/firmware/baseband/proc_fsk.hpp index 2e1dd5680..ee74b756c 100644 --- a/firmware/baseband/proc_fsk.hpp +++ b/firmware/baseband/proc_fsk.hpp @@ -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 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); } }; diff --git a/firmware/common/ais_baseband.cpp b/firmware/common/ais_baseband.cpp index 82ef1459f..476e4b995 100644 --- a/firmware/common/ais_baseband.cpp +++ b/firmware/common/ais_baseband.cpp @@ -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), "" }; diff --git a/firmware/common/bit_pattern.hpp b/firmware/common/bit_pattern.hpp index fd70cdd62..33a3616a5 100644 --- a/firmware/common/bit_pattern.hpp +++ b/firmware/common/bit_pattern.hpp @@ -25,8 +25,29 @@ #include #include +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__*/