diff --git a/include/l2/lower_mac_coding.hpp b/include/l2/lower_mac_coding.hpp index c4fa543..579f135 100644 --- a/include/l2/lower_mac_coding.hpp +++ b/include/l2/lower_mac_coding.hpp @@ -29,9 +29,10 @@ struct LowerMacCoding { * */ template - static auto descramble(const std::array& input, std::array& output, - uint32_t scrambling_code) noexcept -> void { + static auto descramble(const std::array& input, uint32_t scrambling_code) noexcept + -> std::array { static std::map> table_by_scrambling_code; + std::array output{}; static_assert(Size <= 432); @@ -61,6 +62,8 @@ struct LowerMacCoding { for (std::size_t i = 0; i < Size; i++) { output[i] = input[i] ^ table[i]; } + + return output; } /** @@ -68,12 +71,15 @@ struct LowerMacCoding { * */ template - static auto deinterleave(const std::array& data, std::array& res, - const std::size_t a) noexcept -> void { + static auto deinterleave(const std::array& data, const std::size_t a) noexcept + -> std::array { + std::array res{}; for (std::size_t i = 0; i < Size; i++) { auto k = 1 + (a * (i + 1)) % ViterbiCodec::K; res[i] = data[k - 1]; // to interleave: DataOut[i-1] = DataIn[k-1] } + + return res; } /** @@ -126,8 +132,8 @@ struct LowerMacCoding { * */ - static auto reed_muller_3014_decode(const std::array& input, std::array& output) noexcept - -> void { + static auto reed_muller_3014_decode(const std::array& input) noexcept -> std::array { + std::array output; uint8_t q[14][5]; q[0][0] = input[0]; @@ -327,6 +333,8 @@ struct LowerMacCoding { // print_vector(res, 14); // return vector_extract(data, 0, 14); + + return output; } /** diff --git a/src/l2/lower_mac.cpp b/src/l2/lower_mac.cpp index 89f20d5..3e0fff8 100644 --- a/src/l2/lower_mac.cpp +++ b/src/l2/lower_mac.cpp @@ -48,13 +48,11 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs // bb contains AACH // ✅ done std::array bb_input{}; - std::array bb_desc{}; - std::array bb_rm{}; for (auto i = 0; i < 30; i++) { bb_input[i] = frame[252 + i]; } - LowerMacCoding::descramble(bb_input, bb_desc, bsc.scrambling_code); - LowerMacCoding::reed_muller_3014_decode(bb_desc, bb_rm); + + auto bb_rm = LowerMacCoding::reed_muller_3014_decode(LowerMacCoding::descramble(bb_input, bsc.scrambling_code)); auto _aach = AccessAssignmentChannel(burst_type, bsc.time, BitVector(std::vector(bb_rm.cbegin(), bb_rm.cend()))); @@ -64,15 +62,14 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs // see ETSI EN 300 392-2 V3.8.1 (2016-08) Figure 8.6: Error control // structure for π4DQPSK logical channels (part 2) std::array bkn2_input{}; - std::array bkn2_desc{}; - std::array bkn2_dei{}; for (auto i = 0; i < 216; i++) { bkn2_input[i] = frame[282 + i]; } - LowerMacCoding::descramble(bkn2_input, bkn2_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(bkn2_desc, bkn2_dei, 101); - auto bkn2_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn2_dei)); + + auto bkn2_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn2_input, bsc.scrambling_code), 101))); + if (LowerMacCoding::check_crc_16_ccitt<140>(bkn2_bits)) { // SCH/HD or BNCH mapped functions.emplace_back([this, burst_type, bkn2_bits] { @@ -84,28 +81,24 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs // bb contains AACH // ✅ std::array bb_input{}; - std::array bb_desc{}; - std::array bb_rm{}; for (auto i = 0; i < 30; i++) { auto offset = i > 14 ? 266 : 230; bb_input[i] = frame[offset + i]; } - LowerMacCoding::descramble(bb_input, bb_desc, bsc.scrambling_code); - LowerMacCoding::reed_muller_3014_decode(bb_desc, bb_rm); + + auto bb_rm = LowerMacCoding::reed_muller_3014_decode(LowerMacCoding::descramble(bb_input, bsc.scrambling_code)); auto aach = AccessAssignmentChannel(burst_type, bsc.time, BitVector(std::vector(bb_rm.cbegin(), bb_rm.cend()))); // TCH or SCH/F std::array bkn1_input{}; - std::array bkn1_desc{}; - std::array bkn1_dei{}; for (auto i = 0; i < 432; i++) { auto offset = i > 216 ? 282 : 14; bkn1_input[i] = frame[offset + i]; - } - LowerMacCoding::descramble(bkn1_input, bkn1_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(bkn1_desc, bkn1_dei, 103); - auto bkn1_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn1_dei)); + }; + + auto bkn1_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn1_input, bsc.scrambling_code), 103))); if (aach.downlink_usage == DownlinkUsage::Traffic) { // TODO: handle TCH @@ -127,37 +120,31 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs // bb contains AACH // ✅ done std::array bb_input{}; - std::array bb_desc{}; - std::array bb_rm{}; for (auto i = 0; i < 30; i++) { auto offset = i > 14 ? 266 : 230; bb_input[i] = frame[offset + i]; } - LowerMacCoding::descramble(bb_input, bb_desc, bsc.scrambling_code); - LowerMacCoding::reed_muller_3014_decode(bb_desc, bb_rm); + + auto bb_rm = LowerMacCoding::reed_muller_3014_decode(LowerMacCoding::descramble(bb_input, bsc.scrambling_code)); auto aach = AccessAssignmentChannel(burst_type, bsc.time, BitVector(std::vector(bb_rm.cbegin(), bb_rm.cend()))); std::array bkn1_input{}; - std::array bkn1_desc{}; - std::array bkn1_dei{}; for (auto i = 0; i < 216; i++) { bkn1_input[i] = frame[14 + i]; - } - LowerMacCoding::descramble(bkn1_input, bkn1_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(bkn1_desc, bkn1_dei, 101); - auto bkn1_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn1_dei)); + }; + + auto bkn1_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn1_input, bsc.scrambling_code), 101))); std::array bkn2_input{}; - std::array bkn2_desc{}; - std::array bkn2_dei{}; for (auto i = 0; i < 216; i++) { bkn2_input[i] = frame[282 + i]; } - LowerMacCoding::descramble(bkn2_input, bkn2_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(bkn2_desc, bkn2_dei, 101); - auto bkn2_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn2_dei)); + + auto bkn2_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn2_input, bsc.scrambling_code), 101))); if (LowerMacCoding::check_crc_16_ccitt<140>(bkn1_bits)) { if (aach.downlink_usage == DownlinkUsage::Traffic) { @@ -203,15 +190,14 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs } } else if (burst_type == BurstType::ControlUplinkBurst) { std::array cb_input{}; - std::array cb_desc{}; - std::array cb_dei{}; for (auto i = 0; i < 168; i++) { auto offset = i > 84 ? 118 : 4; cb_input[i] = frame[offset + i]; - } - LowerMacCoding::descramble(cb_input, cb_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(cb_desc, cb_dei, 13); - auto cb_bits = LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(cb_dei)); + }; + + auto cb_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(cb_input, bsc.scrambling_code), 13))); if (LowerMacCoding::check_crc_16_ccitt<108>(cb_bits)) { functions.emplace_back([this, burst_type, cb_bits] { @@ -221,18 +207,16 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs } } else if (burst_type == BurstType::NormalUplinkBurst) { std::array bkn1_input{}; - std::array bkn1_desc{}; - std::array bkn1_dei{}; for (auto i = 0; i < 432; i++) { auto offset = i > 216 ? 242 : 4; bkn1_input[i] = frame[offset + i]; } - LowerMacCoding::descramble(bkn1_input, bkn1_desc, bsc.scrambling_code); + // TODO: this can either be a SCH_H or a TCH, depending on the uplink usage marker, but the uplink // and downlink processing are seperated. We assume a SCH_H here. - LowerMacCoding::deinterleave(bkn1_desc, bkn1_dei, 103); - auto bkn1_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn1_dei)); + auto bkn1_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn1_input, bsc.scrambling_code), 103))); if (LowerMacCoding::check_crc_16_ccitt<284>(bkn1_bits)) { // fmt::print("NUB Burst crc good\n"); @@ -245,26 +229,22 @@ auto LowerMac::processChannels(const std::vector& frame, BurstType burs } } else if (burst_type == BurstType::NormalUplinkBurstSplit) { std::array bkn1_input{}; - std::array bkn1_desc{}; - std::array bkn1_dei{}; for (auto i = 0; i < 216; i++) { bkn1_input[i] = frame[4 + i]; } - LowerMacCoding::descramble(bkn1_input, bkn1_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(bkn1_desc, bkn1_dei, 101); - auto bkn1_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn1_dei)); + + auto bkn1_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn1_input, bsc.scrambling_code), 101))); std::array bkn2_input{}; - std::array bkn2_desc{}; - std::array bkn2_dei{}; for (auto i = 0; i < 216; i++) { bkn2_input[i] = frame[242 + i]; - } - LowerMacCoding::descramble(bkn2_input, bkn2_desc, bsc.scrambling_code); - LowerMacCoding::deinterleave(bkn2_desc, bkn2_dei, 101); - auto bkn2_bits = - LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(bkn2_dei)); + }; + + auto bkn2_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23(LowerMacCoding::deinterleave( + LowerMacCoding::descramble(bkn2_input, bsc.scrambling_code), 101))); // STCH + TCH // STCH + STCH @@ -311,14 +291,13 @@ auto LowerMac::process(const std::vector& frame, BurstType burst_type) // sb contains BSCH // ✅ done std::array sb_input{}; - std::array sb_desc{}; - std::array sb_dei{}; for (auto i = 0; i < 30; i++) { sb_input[i] = frame[94 + i]; - } - LowerMacCoding::descramble(sb_input, sb_desc, 0x0003); - LowerMacCoding::deinterleave(sb_desc, sb_dei, 11); - auto sb_bits = LowerMacCoding::viter_bi_decode_1614(viter_bi_codec_1614_, LowerMacCoding::depuncture23(sb_dei)); + }; + + auto sb_bits = LowerMacCoding::viter_bi_decode_1614( + viter_bi_codec_1614_, LowerMacCoding::depuncture23( + LowerMacCoding::deinterleave(LowerMacCoding::descramble(sb_input, 0x0003), 11))); if (LowerMacCoding::check_crc_16_ccitt<76>(sb_bits)) { current_sync = BroadcastSynchronizationChannel(