Line data Source code
1 : /*
2 : * libpoporon - common.h
3 : *
4 : * This file is part of libpoporon.
5 : *
6 : * SPDX-License-Identifier: BSD-3-Clause
7 : */
8 :
9 : #ifndef POPORON_INTERNAL_COMMON_H
10 : #define POPORON_INTERNAL_COMMON_H
11 :
12 : #include <stdbool.h>
13 : #include <stddef.h>
14 : #include <stdint.h>
15 :
16 : #include <poporon.h>
17 : #include <poporon/gf.h>
18 :
19 : #define pmemcpy(dest, src, size) memcpy(dest, src, size)
20 : #define pmemmove(dest, src, size) memmove(dest, src, size)
21 : #define pmemcmp(s1, s2, size) memcmp(s1, s2, size)
22 : #define pmemset(dest, value, size) memset(dest, value, size)
23 : #define pmalloc(size) malloc(size)
24 : #define pcalloc(count, size) calloc(count, size)
25 : #define prealloc(ptr, size) realloc(ptr, size)
26 : #define pfree(ptr) free(ptr)
27 :
28 : #define POPORON_VERSION_ID 20000000
29 :
30 : #ifndef POPORON_BUILDTIME
31 : #define POPORON_BUILDTIME 0
32 : #endif
33 :
34 : typedef struct _poporon_rs_t poporon_rs_t;
35 : typedef struct _poporon_bch_t poporon_bch_t;
36 : typedef struct _poporon_ldpc_t poporon_ldpc_t;
37 :
38 : typedef struct {
39 : uint16_t *coeff;
40 : uint32_t order;
41 : } polynomial_t;
42 :
43 : struct _poporon_gf_t {
44 : uint8_t symbol_size;
45 : uint16_t field_size;
46 : uint16_t *exp;
47 : uint16_t *log;
48 : };
49 :
50 : struct _poporon_erasure_t {
51 : uint32_t capacity;
52 : uint32_t erasure_count;
53 : uint32_t *erasure_positions;
54 : uint16_t *corrections;
55 : };
56 :
57 : struct _poporon_t {
58 : poporon_fec_type_t fec_type;
59 :
60 : union {
61 : struct {
62 : poporon_rs_t *rs;
63 : poporon_erasure_t *erasure;
64 : uint16_t *ext_syndrome;
65 : size_t last_corrected;
66 : } rs;
67 :
68 : struct {
69 : poporon_ldpc_t *ldpc;
70 : const int8_t *soft_llr;
71 : size_t soft_llr_size;
72 : uint32_t max_iterations;
73 : uint32_t last_iterations;
74 : bool use_soft_decode;
75 : } ldpc;
76 :
77 : struct {
78 : poporon_bch_t *bch;
79 : int32_t last_num_errors;
80 : } bch;
81 : } ctx;
82 : };
83 :
84 162626 : static inline uint16_t field_add(uint16_t l, uint16_t r)
85 : {
86 162626 : return l ^ r;
87 : }
88 :
89 184 : static inline uint16_t field_sub(uint16_t l, uint16_t r)
90 : {
91 184 : return l ^ r;
92 : }
93 :
94 184 : static inline uint16_t field_sum(uint16_t elem, uint32_t n)
95 : {
96 184 : return (n % 2) ? elem : 0;
97 : }
98 :
99 21423 : static inline uint16_t field_mul(poporon_gf_t *gf, uint16_t l, uint16_t r)
100 : {
101 21423 : if (l == 0 || r == 0) {
102 59 : return 0;
103 : }
104 :
105 21364 : return gf->exp[(uint32_t)gf->log[l] + (uint32_t)gf->log[r]];
106 : }
107 :
108 1244 : static inline uint16_t field_div(poporon_gf_t *gf, uint16_t l, uint16_t r)
109 : {
110 1244 : if (l == 0) {
111 2 : return 0;
112 : }
113 1242 : if (r == 0) {
114 0 : return 0;
115 : }
116 :
117 1242 : return gf->exp[(uint32_t)gf->field_size + (uint32_t)gf->log[l] - (uint32_t)gf->log[r]];
118 : }
119 :
120 97920 : static inline uint16_t field_mul_log(poporon_gf_t *gf, uint16_t l, uint16_t r)
121 : {
122 97920 : uint32_t res = (uint32_t)l + (uint32_t)r;
123 :
124 97920 : if (res >= gf->field_size) {
125 28698 : res -= gf->field_size;
126 : }
127 :
128 97920 : return (uint16_t)res;
129 : }
130 :
131 448 : static inline uint16_t field_div_log(poporon_gf_t *gf, uint16_t l, uint16_t r)
132 : {
133 448 : uint32_t res = (uint32_t)gf->field_size + (uint32_t)l - (uint32_t)r;
134 :
135 448 : if (res >= gf->field_size) {
136 0 : res -= gf->field_size;
137 : }
138 :
139 448 : return (uint16_t)res;
140 : }
141 :
142 141079 : static inline uint16_t field_mul_log_element(poporon_gf_t *gf, uint16_t l, uint16_t r)
143 : {
144 141079 : return gf->exp[(uint32_t)l + (uint32_t)r];
145 : }
146 :
147 21454 : static inline uint16_t field_pow(poporon_gf_t *gf, uint16_t elem, int power)
148 : {
149 : int res_log, mod;
150 :
151 21454 : if (elem == 0) {
152 148 : return 0;
153 : }
154 :
155 21306 : res_log = (int)gf->log[elem] * power;
156 21306 : mod = res_log % (int)gf->field_size;
157 :
158 21306 : if (mod < 0) {
159 0 : mod += (int)gf->field_size;
160 : }
161 :
162 21306 : return gf->exp[mod];
163 : }
164 :
165 : poporon_rs_t *poporon_rs_create(uint8_t symbol_size, uint16_t primitive_polynomial, uint16_t first_consecutive_root,
166 : uint16_t primitive_element, uint8_t num_roots);
167 : void poporon_rs_destroy(poporon_rs_t *rs);
168 :
169 : poporon_bch_t *poporon_bch_create(uint8_t symbol_size, uint16_t generator_polynomial, uint8_t t);
170 : void poporon_bch_destroy(poporon_bch_t *bch);
171 :
172 : uint16_t poporon_bch_get_codeword_length(const poporon_bch_t *bch);
173 : uint16_t poporon_bch_get_data_length(const poporon_bch_t *bch);
174 : uint8_t poporon_bch_get_correction_capability(const poporon_bch_t *bch);
175 : bool poporon_bch_encode(poporon_bch_t *bch, uint32_t data, uint32_t *codeword);
176 : bool poporon_bch_decode(poporon_bch_t *bch, uint32_t received, uint32_t *corrected, int32_t *num_errors);
177 : uint32_t poporon_bch_extract_data(const poporon_bch_t *bch, uint32_t codeword);
178 :
179 : #endif /* POPORON_INTERNAL_COMMON_H */
|