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