File: qa_mobitex_fec.py

package info (click to toggle)
gr-satellites 5.8.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,836 kB
  • sloc: python: 29,546; cpp: 5,448; ansic: 1,247; sh: 118; makefile: 24
file content (124 lines) | stat: -rw-r--r-- 3,659 bytes parent folder | download
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)