File: stx_deframer.cpp

package info (click to toggle)
satdump 1.2.2%2Bgb79af48-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 81,648 kB
  • sloc: cpp: 276,768; ansic: 164,598; lisp: 1,219; sh: 283; xml: 106; makefile: 7
file content (120 lines) | stat: -rw-r--r-- 3,422 bytes parent folder | download | duplicates (2)
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
#include "stx_deframer.h"
#include <cstdint>
#include <cstring>

namespace orbcomm
{
    STXDeframer::STXDeframer(int cadu_size) : FRM_SIZE(cadu_size)
    {
        frame_buffer = new uint8_t[FRM_SIZE];
    }

    STXDeframer::~STXDeframer()
    {
        delete[] frame_buffer;
    }

    int STXDeframer::getState()
    {
        return d_state;
    }

    int STXDeframer::work(uint8_t *input, int size, uint8_t *output)
    {
        int frame_count = 0;

        for (int ibit = 0; ibit < size; ibit++) // We work bit-per-bit
        {
            shifter = (shifter << 1 | input[ibit]) & 0xFFFFFF;

            if (in_frame)
            {
                write_bit(input[ibit] ^ bit_inversion);

                if (bit_of_frame == FRM_SIZE) // Write frame out
                {
                    memcpy(&output[frame_count * (FRM_SIZE / 8)], frame_buffer, FRM_SIZE / 8);
                    frame_count++;
                }
                else if (bit_of_frame == FRM_SIZE + FRM_ASM_SIZE - 1) // Skip to the next ASM
                {
                    in_frame = false;
                }

                continue;
            }

            if (d_state == STATE_NOSYNC)
            {
                if (shifter == FRM_ASM)
                {
                    bit_inversion = false;
                    reset_frame();
                    in_frame = true;
                    d_state = STATE_SYNCING;
                    d_good_asm = d_invalid_asm = 0;
                }
                else if (shifter == FRM_ASM_INV)
                {
                    bit_inversion = true;
                    reset_frame();
                    in_frame = true;
                    d_state = STATE_SYNCING;
                    d_good_asm = d_invalid_asm = 0;
                }
            }
            else if (d_state == STATE_SYNCING)
            {
                if (compare_32(shifter, bit_inversion ? FRM_ASM_INV : FRM_ASM) < d_state)
                {
                    reset_frame();
                    in_frame = true;
                    d_invalid_asm = 0;
                    d_good_asm++;

                    if (d_good_asm > 10)
                        d_state = STATE_SYNCED;
                }
                else
                {
                    d_invalid_asm++;
                    d_good_asm = 0;

                    if (d_invalid_asm > 2)
                    {
                        d_state = STATE_NOSYNC;
                    }
                }
            }
            else if (d_state == STATE_SYNCED)
            {
                if (compare_32(shifter, bit_inversion ? FRM_ASM_INV : FRM_ASM) < d_state)
                {
                    reset_frame();
                    in_frame = true;
                }
                else
                {
                    d_good_asm = d_invalid_asm = 0;
                    d_state = STATE_NOSYNC; // Reset to hard NOSYNC, so we correct for a possible new inversion state
                }
            }
        }

        return frame_count;
    }

    void STXDeframer::write_bit(uint8_t b)
    {
        frame_buffer[bit_of_frame / 8] = frame_buffer[bit_of_frame / 8] << 1 | b;
        bit_of_frame++;
    }

    void STXDeframer::reset_frame()
    {
        memset(frame_buffer, 0, FRM_SIZE / 8);
        bit_of_frame = 0;
        for (int i = FRM_ASM_SIZE - 1; i >= 0; i--)
            write_bit((FRM_ASM >> i) & 1);
    }
}