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
224namespace gr {
225
226namespace satnogs {
227
228/**
229 * @brief Several bit-level utility methods, frequently used in the
230 * encoding/decoding process
231 *
232 * @ingroup satnogs
233 */
234class utils
235{
236public:
237 static double mape(double ref, double estimation);
238
239 static uint64_t htonll(uint64_t x);
240
241 static uint64_t ntohll(uint64_t x);
242
243 static uint32_t bit_count(uint32_t x);
244
245 static uint8_t reverse_byte(uint8_t b);
246
247 static uint32_t reverse_uint32_bytes(uint32_t i);
248
249 static uint64_t reverse_uint64_bytes(uint64_t x);
250
251 static void print_pdu(const uint8_t* buf, size_t len);
252
253 /**
254 * Template function that unpack the bits of the list-like object with numbers in
255 * @param out the list with the unpacked bits
256 * @param in the list with the packed bits
257 * @param len the size of the in
258 * @return the size of the out
259 */
260 template <class T, class U, bool S>
261 static size_t packed_to_unpacked(T out, const U in, size_t len = 0)
262 {
264 }
265
266 /**
267 * Template function that pack the bits of the list-like object with numbers in
268 * @param out the list with the packed bits
269 * @param in the list with the unpacked bits
270 * @param len the size of the in
271 * @return the size of the out
272 */
273 template <class T, class U, bool S>
274 static size_t unpacked_to_packed(T out, const U in, size_t len = 0)
275 {
277 }
278
279private:
280 static constexpr uint8_t s_bytes_reversed[256] = {
281 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30,
282 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98,
283 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64,
284 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC,
285 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02,
286 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2,
287 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A,
288 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
289 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E,
290 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81,
291 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71,
292 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
293 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15,
294 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD,
295 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43,
296 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
297 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B,
298 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97,
299 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F,
300 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
301 };
302};
303
304} // namespace satnogs
305
306} // namespace gr
307
308#endif /* INCLUDE_SATNOGS_UTILS_H_ */
Several bit-level utility methods, frequently used in the encoding/decoding process.
Definition: utils.h:235
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:274
static size_t packed_to_unpacked(T out, const U in, size_t len=0)
Definition: utils.h:261
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