Line data Source code
1 : /**
2 : * @file mask.c
3 : * @brief CCSDS 124.0-B-1 mask update logic.
4 : *
5 : * @cond INTERNAL
6 : * ============================================================================
7 : * _____ ____
8 : * |_ _|_ _ _ __ __ _ __ _ _ __ __ _ / ___| _ __ __ _ ___ ___
9 : * | |/ _` | '_ \ / _` |/ _` | '__/ _` | \___ \| '_ \ / _` |/ __/ _ \
10 : * | | (_| | | | | (_| | (_| | | | (_| | ___) | |_) | (_| | (_| __/
11 : * |_|\__,_|_| |_|\__,_|\__, |_| \__,_| |____/| .__/ \__,_|\___\___|
12 : * |___/ |_|
13 : * ============================================================================
14 : * @endcond
15 : *
16 : * Implements CCSDS 124.0-B-1 Section 4 (Mask Update):
17 : * - Build Vector Update (Equation 6)
18 : * - Mask Vector Update (Equation 7)
19 : * - Change Vector Computation (Equation 8)
20 : *
21 : * @authors Georges Labrèche <georges@tanagraspace.com> — https://georges.fyi
22 : * @authors Claude Code (Anthropic) <noreply@anthropic.com>
23 : *
24 : * @see https://ccsds.org/Pubs/124x0b1.pdf CCSDS 124.0-B-1 Standard
25 : */
26 :
27 : #include "ccsds124.h"
28 :
29 : /**
30 : * @name Build Vector Functions
31 : *
32 : * CCSDS Equation 6:
33 : * - Bₜ = (Iₜ XOR Iₜ₋₁) OR Bₜ₋₁ (if t > 0 and ṗₜ = 0)
34 : * - Bₜ = 0 (otherwise: t=0 or ṗₜ=1)
35 : *
36 : * The build vector accumulates bits that have changed over time.
37 : * When new_mask_flag is set, the build is used to replace the mask
38 : * and is then reset to zero.
39 : * @{
40 : */
41 :
42 :
43 189102 : void ccsds124_update_build(
44 : bitvector_t *build,
45 : const bitvector_t *input,
46 : const bitvector_t *prev_input,
47 : int new_mask_flag,
48 : size_t t
49 : ) {
50 : /* Case 1: t=0 or new_mask_flag set → reset build to 0 */
51 189102 : if ((t == 0U) || (new_mask_flag != 0)) {
52 10707 : bitvector_zero(build);
53 : } else {
54 : /* Case 2: Normal operation (t > 0 and new_mask_flag = 0)
55 : * Bₜ = (Iₜ XOR Iₜ₋₁) OR Bₜ₋₁
56 : */
57 :
58 : /* Create temporary vector for changes */
59 : bitvector_t changes;
60 178395 : (void)bitvector_init(&changes, build->length);
61 :
62 : /* Calculate changes: Iₜ XOR Iₜ₋₁ */
63 178395 : bitvector_xor(&changes, input, prev_input);
64 :
65 : /* Update build: Bₜ = changes OR Bₜ₋₁ */
66 178395 : bitvector_or(build, &changes, build);
67 : }
68 189102 : }
69 :
70 : /** @} */ /* End of Build Vector Functions */
71 :
72 : /**
73 : * @name Mask Vector Functions
74 : *
75 : * CCSDS Equation 7:
76 : * - Mₜ = (Iₜ XOR Iₜ₋₁) OR Mₜ₋₁ (if ṗₜ = 0)
77 : * - Mₜ = (Iₜ XOR Iₜ₋₁) OR Bₜ₋₁ (if ṗₜ = 1)
78 : *
79 : * The mask tracks which bits are unpredictable.
80 : * When new_mask_flag is set, the mask is replaced with the build vector.
81 : * @{
82 : */
83 :
84 :
85 189100 : void ccsds124_update_mask(
86 : bitvector_t *mask,
87 : const bitvector_t *input,
88 : const bitvector_t *prev_input,
89 : const bitvector_t *build_prev,
90 : int new_mask_flag
91 : ) {
92 : /* Create temporary vector for changes */
93 : bitvector_t changes;
94 189100 : (void)bitvector_init(&changes, mask->length);
95 :
96 : /* Calculate changes: Iₜ XOR Iₜ₋₁ */
97 189100 : bitvector_xor(&changes, input, prev_input);
98 :
99 189100 : if (new_mask_flag != 0) {
100 : /* Case 1: new_mask_flag set → Mₜ = (Iₜ XOR Iₜ₋₁) OR Bₜ₋₁ */
101 10705 : bitvector_or(mask, &changes, build_prev);
102 : } else {
103 : /* Case 2: Normal operation → Mₜ = (Iₜ XOR Iₜ₋₁) OR Mₜ₋₁ */
104 178395 : bitvector_or(mask, &changes, mask);
105 : }
106 189100 : }
107 :
108 : /** @} */ /* End of Mask Vector Functions */
109 :
110 : /**
111 : * @name Change Vector Functions
112 : *
113 : * CCSDS Equation 8:
114 : * - Dₜ = Mₜ XOR Mₜ₋₁
115 : *
116 : * The change vector tracks which mask bits changed between time steps.
117 : * This is used in encoding to communicate mask updates.
118 : *
119 : * At t=0, the caller sets Mₜ₋₁ = M₀ so that D₀ = M₀ XOR M₀ = 0
120 : * (no change at initialization).
121 : * @{
122 : */
123 :
124 :
125 189249 : void ccsds124_compute_change(
126 : bitvector_t *change,
127 : const bitvector_t *mask,
128 : const bitvector_t *prev_mask,
129 : size_t t
130 : ) {
131 : (void)t; /* Always use XOR — caller sets prev_mask appropriately */
132 : /* Dₜ = Mₜ XOR Mₜ₋₁ */
133 189249 : bitvector_xor(change, mask, prev_mask);
134 189249 : }
135 :
136 : /** @} */ /* End of Change Vector Functions */
|