1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2025 Fabian P. Schmidt <kerel@mailbox.org>
#
# This file is part of gr-satellites
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
import copy
from gnuradio import gr, blocks, gr_unittest
from gnuradio.pdu import pdu_lambda, pdu_set
import numpy as np
import pmt
# bootstrap satellites module, even from build dir
try:
import python as satellites
except ImportError:
pass
else:
import sys
sys.modules['satellites'] = satellites
from satellites.mobitex_fec import (
init_syndrome_table, encode, decode, Status,
pack_2b, unpack_2b,
)
class qa_mobitex_fec(gr_unittest.TestCase):
def test_init_syndrome_table(self):
desired_syndrom_table = {
1: 0, 2: 1, 4: 2, 8: 3, 5: 4, 6: 5,
9: 6, 10: 7, 7: 8, 11: 9, 13: 10, 14: 11}
actual_syndrom_table = init_syndrome_table()
self.assertEqual(desired_syndrom_table, actual_syndrom_table)
def test_encode(self):
# Example with zero bit errors
message = 0x2C
desired_codeword = 0x2C8
actual_codeword = encode(message)
self.assertEqual(actual_codeword, desired_codeword)
def test_decode(self):
codeword = 0x2C8
desired_message = 0x2C
desired_status = Status.NO_ERROR
actual_message, _, actual_status = decode(codeword)
self.assertEqual(actual_status, desired_status)
self.assertEqual(actual_message, desired_message)
def test_decode2(self):
# Example with single-bit error
codeword = 0x2C8
codeword = codeword | 0b0010_0000
desired_message = 0x2C
desired_status = Status.ERROR_CORRECTED
actual_message, _, actual_status = decode(codeword)
self.assertEqual(actual_status, desired_status)
self.assertEqual(actual_message, desired_message)
def test_decode3(self):
# Example with two bit errors; collision and thus invalid correction
codeword = 0x2C8
codeword = codeword | 0b0010_0010
desired_status = Status.ERROR_CORRECTED
desired_message = 0x2E
actual_message, _, actual_status = decode(codeword)
self.assertEqual(actual_status, desired_status)
self.assertEqual(actual_message, desired_message)
def test_pack2b(self):
codeword0, codeword1 = 0x580, 0x444
desired_code = bytes.fromhex('580444')
actual_code = pack_2b(codeword0, codeword1)
self.assertEqual(desired_code, actual_code)
def test_unpack2b(self):
code = bytes.fromhex('AFFEFE')
desired_codeword0 = 0xaff
desired_codeword1 = 0xefe
actual_codeword0, actual_codeword1 = unpack_2b(code)
self.assertEqual(actual_codeword0, desired_codeword0)
self.assertEqual(actual_codeword1, desired_codeword1)
def test_edge_cases(self):
# Test edge cases and error conditions
# Test all possible 8-bit values
for i in range(256):
codeword = encode(i)
fec = codeword & 0xf
assert 0 <= fec <= 0xF
decoded, _, status = decode(codeword)
assert status == status.NO_ERROR
assert decoded == i
# For one example message,
# test all possible single-bit errors.
message = 0x2C
codeword = encode(message)
for bit in range(12):
corrupted = codeword ^ (1 << bit)
decoded, _, status = decode(corrupted)
assert status == Status.ERROR_CORRECTED
assert decoded == message
if __name__ == '__main__':
gr_unittest.run(qa_mobitex_fec)
|