1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/* -*- c++ -*- */
/* Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/digital/lfsr.h>
#include <gnuradio/digital/packet_header_ofdm.h>
namespace gr {
namespace digital {
int _get_header_len_from_occupied_carriers(
const std::vector<std::vector<int>>& occupied_carriers, int n_syms)
{
int header_len = 0;
for (int i = 0; i < n_syms; i++) {
header_len += occupied_carriers[i].size();
}
return header_len;
}
packet_header_ofdm::sptr
packet_header_ofdm::make(const std::vector<std::vector<int>>& occupied_carriers,
int n_syms,
const std::string& len_tag_key,
const std::string& frame_len_tag_key,
const std::string& num_tag_key,
int bits_per_header_sym,
int bits_per_payload_sym,
bool scramble_header)
{
return packet_header_ofdm::sptr(new packet_header_ofdm(occupied_carriers,
n_syms,
len_tag_key,
frame_len_tag_key,
num_tag_key,
bits_per_header_sym,
bits_per_payload_sym,
scramble_header));
}
packet_header_ofdm::packet_header_ofdm(
const std::vector<std::vector<int>>& occupied_carriers,
int n_syms,
const std::string& len_tag_key,
const std::string& frame_len_tag_key,
const std::string& num_tag_key,
int bits_per_header_sym,
int bits_per_payload_sym,
bool scramble_header)
: packet_header_default(
_get_header_len_from_occupied_carriers(occupied_carriers, n_syms),
len_tag_key,
num_tag_key,
bits_per_header_sym),
d_frame_len_tag_key(pmt::string_to_symbol(frame_len_tag_key)),
d_occupied_carriers(occupied_carriers),
d_bits_per_payload_sym(bits_per_payload_sym),
d_scramble_mask(d_header_len, 0)
{
// Init scrambler mask
if (scramble_header) {
// These are just random values which already have OK PAPR:
gr::digital::lfsr shift_reg(0x8a, 0x6f, 7);
for (int i = 0; i < d_header_len; i++) {
for (int k = 0; k < bits_per_header_sym; k++) {
d_scramble_mask[i] ^= shift_reg.next_bit() << k;
}
}
}
}
packet_header_ofdm::~packet_header_ofdm() {}
bool packet_header_ofdm::header_formatter(long packet_len,
unsigned char* out,
const std::vector<tag_t>& tags)
{
bool ret_val = packet_header_default::header_formatter(packet_len, out, tags);
for (int i = 0; i < d_header_len; i++) {
out[i] ^= d_scramble_mask[i];
}
return ret_val;
}
bool packet_header_ofdm::header_parser(const unsigned char* in, std::vector<tag_t>& tags)
{
std::vector<unsigned char> in_descrambled(d_header_len, 0);
for (int i = 0; i < d_header_len; i++) {
in_descrambled[i] = in[i] ^ d_scramble_mask[i];
}
if (!packet_header_default::header_parser(&in_descrambled[0], tags)) {
return false;
}
int packet_len = 0; // # of complex symbols in this frame
for (size_t i = 0; i < tags.size(); i++) {
if (pmt::equal(tags[i].key, d_len_tag_key)) {
// Convert bytes to complex symbols:
packet_len = pmt::to_long(tags[i].value) * 8 / d_bits_per_payload_sym;
if (pmt::to_long(tags[i].value) * 8 % d_bits_per_payload_sym) {
packet_len++;
}
tags[i].value = pmt::from_long(packet_len);
break;
}
}
// To figure out how many payload OFDM symbols there are in this frame,
// we need to go through the carrier allocation and count the number of
// allocated carriers per OFDM symbol.
// frame_len == # of payload OFDM symbols in this frame
int frame_len = 0;
size_t k = 0; // position in the carrier allocation map
int symbols_accounted_for = 0;
while (symbols_accounted_for < packet_len) {
frame_len++;
symbols_accounted_for += d_occupied_carriers[k].size();
k = (k + 1) % d_occupied_carriers.size();
}
tag_t tag;
tag.key = d_frame_len_tag_key;
tag.value = pmt::from_long(frame_len);
tags.push_back(tag);
return true;
}
} /* namespace digital */
} /* namespace gr */
|