GNU Radio's SATNOGS Package
utils.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
4 *
5 * Copyright (C) 2016,2018,2019,2022 Libre Space Foundation <http://libre.space/>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef INCLUDE_SATNOGS_UTILS_H_
22#define INCLUDE_SATNOGS_UTILS_H_
23
24#include <arpa/inet.h>
25#include <itpp/itbase.h>
26#include <cmath>
27#include <cstdint>
28#include <cstdlib>
29
30template <class T, class U, bool S>
32{
33public:
34 static size_t packed_to_unpacked(T out, const U in, size_t len) { return 0; }
35
36 static size_t unpacked_to_packed(U out, const T in, size_t len) { return 0; }
37};
38
39template <>
40class utils_helper<uint8_t*, uint8_t*, false>
41{
42public:
43 static size_t packed_to_unpacked(uint8_t* out, const uint8_t* in, size_t len)
44 {
45 if (!out || !in || !len) {
46 return 0;
47 }
48
49 for (size_t i = 0; i < len; i++) {
50 *out++ = (in[i] >> 7) & 0x1;
51 *out++ = (in[i] >> 6) & 0x1;
52 *out++ = (in[i] >> 5) & 0x1;
53 *out++ = (in[i] >> 4) & 0x1;
54 *out++ = (in[i] >> 3) & 0x1;
55 *out++ = (in[i] >> 2) & 0x1;
56 *out++ = (in[i] >> 1) & 0x1;
57 *out++ = in[i] & 0x1;
58 }
59
60 return len * 8;
61 }
62
63 static size_t unpacked_to_packed(uint8_t* out, const uint8_t* in, size_t len)
64 {
65 if (!out || !in || !len) {
66 return 0;
67 }
68
69 struct h {
70 uint8_t shift : 3;
71 } x = { .shift = 7 };
72
73 memset(out, 0, static_cast<size_t>(std::ceil(len / 8.0)));
74 for (size_t i = 0; i < len; i++) {
75 out[i / 8] |= ((in[i] & 0x1) << x.shift--);
76 }
77
78 return static_cast<size_t>(std::ceil(len / 8.0));
79 }
80};
81
82template <>
83class utils_helper<int8_t*, uint8_t*, true>
84{
85public:
86 static size_t packed_to_unpacked(int8_t* out, const uint8_t* in, size_t len)
87 {
88 if (!out || !in || !len) {
89 return 0;
90 }
91
92 for (size_t i = 0; i < len; ++i) {
93 *out++ = (((in[i] >> 7) & 0x1) * 255) - 128;
94 *out++ = (((in[i] >> 6) & 0x1) * 255) - 128;
95 *out++ = (((in[i] >> 5) & 0x1) * 255) - 128;
96 *out++ = (((in[i] >> 4) & 0x1) * 255) - 128;
97 *out++ = (((in[i] >> 3) & 0x1) * 255) - 128;
98 *out++ = (((in[i] >> 2) & 0x1) * 255) - 128;
99 *out++ = (((in[i] >> 1) & 0x1) * 255) - 128;
100 *out++ = ((in[i] & 0x1) * 255) - 128;
101 }
102
103 return len * 8;
104 }
105
106 static size_t unpacked_to_packed(uint8_t* out, const int8_t* in, size_t len)
107 {
108 if (!out || !in || !len) {
109 return 0;
110 }
111
112 struct h {
113 uint8_t shift : 3;
114 } x = { .shift = 7 };
115
116 memset(out, 0, static_cast<size_t>(std::ceil(len / 8.0)));
117 for (size_t i = 0; i < len; i++) {
118 uint8_t bit = in[i] > 0 ? 1 : 0;
119 out[i / 8] |= (bit << x.shift--);
120 }
121
122 return static_cast<size_t>(std::ceil(len / 8.0));
123 }
124};
125
126template <>
127class utils_helper<itpp::Vec<uint8_t>&, itpp::bvec&, false>
128{
129public:
130 static size_t
131 packed_to_unpacked(itpp::Vec<uint8_t>& out, const itpp::bvec& in, size_t len = 0)
132 {
133 if (!out.size() || !in.size()) {
134 return 0;
135 }
136
137 size_t j = 0;
138 for (auto i = 0; i < in.size(); i++) {
139 out[j++] = (in[i] >> 7) & 0x1;
140 out[j++] = (in[i] >> 6) & 0x1;
141 out[j++] = (in[i] >> 5) & 0x1;
142 out[j++] = (in[i] >> 4) & 0x1;
143 out[j++] = (in[i] >> 3) & 0x1;
144 out[j++] = (in[i] >> 2) & 0x1;
145 out[j++] = (in[i] >> 1) & 0x1;
146 out[j++] = static_cast<bool>(in[i] & itpp::bin(0x1));
147 }
148
149 return j;
150 }
151
152 static size_t
153 unpacked_to_packed(itpp::bvec& out, const itpp::Vec<uint8_t>& in, size_t len = 0)
154 {
155 if (!out.size() || !in.size()) {
156 return 0;
157 }
158
159 struct h {
160 uint8_t shift : 3;
161 } x = { .shift = 7 };
162
163 for (size_t i = 0; i < static_cast<size_t>(std::ceil(in.size() / 8.0)); i++) {
164 out[i] = 0;
165 }
166 for (auto i = 0; i < in.size(); i++) {
167 ;
168 out[i / 8] |= ((in[i] & 0x1) << x.shift--);
169 }
170
171 return static_cast<size_t>(std::ceil(in.size() / 8.0));
172 }
173};
174
175template <>
176class utils_helper<itpp::Vec<int8_t>&, itpp::bvec&, true>
177{
178public:
179 static size_t
180 packed_to_unpacked(itpp::Vec<int8_t>& out, const itpp::bvec& in, size_t len = 0)
181 {
182 if (!out.size() || !in.size()) {
183 return 0;
184 }
185
186 size_t j = 0;
187 for (auto i = 0; i < in.size(); ++i) {
188 out[j++] = (((in[i] >> 7) & 0x1) * 255) - 128;
189 out[j++] = (((in[i] >> 6) & 0x1) * 255) - 128;
190 out[j++] = (((in[i] >> 5) & 0x1) * 255) - 128;
191 out[j++] = (((in[i] >> 4) & 0x1) * 255) - 128;
192 out[j++] = (((in[i] >> 3) & 0x1) * 255) - 128;
193 out[j++] = (((in[i] >> 2) & 0x1) * 255) - 128;
194 out[j++] = (((in[i] >> 1) & 0x1) * 255) - 128;
195 out[j++] = (static_cast<bool>(in[i] & itpp::bin(0x1)) * 255) - 128;
196 }
197
198 return j;
199 }
200
201 static size_t
202 unpacked_to_packed(itpp::bvec& out, const itpp::Vec<int8_t>& in, size_t len = 0)
203 {
204 if (!out.size() || !in.size()) {
205 return 0;
206 }
207
208 struct h {
209 uint8_t shift : 3;
210 } x = { .shift = 7 };
211
212 for (auto i = 0; i < static_cast<int>(std::ceil(in.size() / 8.0)); i++) {
213 out[i] = 0;
214 }
215 for (auto i = 0; i < in.size(); i++) {
216 uint8_t bit = in[i] > 0 ? 1 : 0;
217 out[i / 8] |= (bit << x.shift--);
218 }
219
220 return static_cast<size_t>(std::ceil(in.size() / 8.0));
221 }
222};
223
224static size_t packed_to_unpacked(uint8_t* out, const uint8_t* in, size_t len)
225{
226 if (!out || !in || !len) {
227 return 0;
228 }
229 for (size_t i = 0; i < len; i++) {
230 *out++ = (in[i] >> 7) & 0x1;
231 *out++ = (in[i] >> 6) & 0x1;
232 *out++ = (in[i] >> 5) & 0x1;
233 *out++ = (in[i] >> 4) & 0x1;
234 *out++ = (in[i] >> 3) & 0x1;
235 *out++ = (in[i] >> 2) & 0x1;
236 *out++ = (in[i] >> 1) & 0x1;
237 *out++ = (in[i]) & 0x1;
238 }
239 return len * 8;
240}
241
242
243static size_t unpacked_to_packed(uint8_t* out, const uint8_t* in, size_t len)
244{
245 if (!out || !in || !len) {
246 return 0;
247 }
248 struct h {
249 uint8_t shift : 3;
250 };
251 struct h x;
252 x.shift = 7;
253 memset(out, 0, static_cast<size_t>(std::ceil(len / 8.0)));
254 for (size_t i = 0; i < len; i++) {
255 out[i / 8] |= ((in[i] & 0x1) << x.shift--);
256 }
257 return static_cast<size_t>(std::ceil(len / 8.0));
258}
259
260namespace gr {
261
262namespace satnogs {
263
264/**
265 * @brief Several bit-level utility methods, frequently used in the
266 * encoding/decoding process
267 *
268 * @ingroup satnogs
269 */
270class utils
271{
272public:
273 static double mape(double ref, double estimation);
274
275 static uint64_t htonll(uint64_t x);
276
277 static uint64_t ntohll(uint64_t x);
278
279 static uint32_t bit_count(uint32_t x);
280
281 static uint8_t reverse_byte(uint8_t b);
282
283 static uint32_t reverse_uint32_bytes(uint32_t i);
284
285 static uint64_t reverse_uint64_bytes(uint64_t x);
286
287 static void print_pdu(const uint8_t* buf, size_t len);
288
289 /**
290 * Template function that unpack the bits of the list-like object with numbers in
291 * @param out the list with the unpacked bits
292 * @param in the list with the packed bits
293 * @param len the size of the in
294 * @return the size of the out
295 */
296 template <class T, class U, bool S>
297 static size_t packed_to_unpacked(T out, const U in, size_t len = 0)
298 {
300 }
301
302 /**
303 * Template function that pack the bits of the list-like object with numbers in
304 * @param out the list with the packed bits
305 * @param in the list with the unpacked bits
306 * @param len the size of the in
307 * @return the size of the out
308 */
309 template <class T, class U, bool S>
310 static size_t unpacked_to_packed(T out, const U in, size_t len = 0)
311 {
313 }
314
315private:
316 static constexpr uint8_t s_bytes_reversed[256] = {
317 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30,
318 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98,
319 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64,
320 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC,
321 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02,
322 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2,
323 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A,
324 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
325 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E,
326 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81,
327 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71,
328 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
329 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15,
330 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD,
331 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43,
332 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
333 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B,
334 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97,
335 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F,
336 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
337 };
338};
339
340} // namespace satnogs
341
342} // namespace gr
343
344#endif /* INCLUDE_SATNOGS_UTILS_H_ */
Several bit-level utility methods, frequently used in the encoding/decoding process.
Definition: utils.h:271
static void print_pdu(const uint8_t *buf, size_t len)
static uint64_t htonll(uint64_t x)
static size_t unpacked_to_packed(T out, const U in, size_t len=0)
Definition: utils.h:310
static size_t packed_to_unpacked(T out, const U in, size_t len=0)
Definition: utils.h:297
static uint64_t ntohll(uint64_t x)
static uint32_t reverse_uint32_bytes(uint32_t i)
static uint64_t reverse_uint64_bytes(uint64_t x)
static uint32_t bit_count(uint32_t x)
static uint8_t reverse_byte(uint8_t b)
static double mape(double ref, double estimation)
static size_t unpacked_to_packed(uint8_t *out, const int8_t *in, size_t len)
Definition: utils.h:106
static size_t packed_to_unpacked(int8_t *out, const uint8_t *in, size_t len)
Definition: utils.h:86
static size_t unpacked_to_packed(itpp::bvec &out, const itpp::Vec< int8_t > &in, size_t len=0)
Definition: utils.h:202
static size_t packed_to_unpacked(itpp::Vec< int8_t > &out, const itpp::bvec &in, size_t len=0)
Definition: utils.h:180
static size_t unpacked_to_packed(itpp::bvec &out, const itpp::Vec< uint8_t > &in, size_t len=0)
Definition: utils.h:153
static size_t packed_to_unpacked(itpp::Vec< uint8_t > &out, const itpp::bvec &in, size_t len=0)
Definition: utils.h:131
static size_t packed_to_unpacked(uint8_t *out, const uint8_t *in, size_t len)
Definition: utils.h:43
static size_t unpacked_to_packed(uint8_t *out, const uint8_t *in, size_t len)
Definition: utils.h:63
Definition: utils.h:32
static size_t unpacked_to_packed(U out, const T in, size_t len)
Definition: utils.h:36
static size_t packed_to_unpacked(T out, const U in, size_t len)
Definition: utils.h:34
int j
Definition: decode_rs.h:73
int i
Definition: decode_rs.h:73
data_t b[NROOTS+1]
Definition: decode_rs.h:77
memset(parity, 0, NROOTS *sizeof(data_t))
CONSTCD14 To ceil(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1238
Definition: amsat_duv_decoder.h:29
static size_t packed_to_unpacked(uint8_t *out, const uint8_t *in, size_t len)
Definition: utils.h:224
static size_t unpacked_to_packed(uint8_t *out, const uint8_t *in, size_t len)
Definition: utils.h:243