GNU Radio C++ API Reference
3.10.12.0
The Free & Open Software Radio Ecosystem
Loading...
Searching...
No Matches
header_buffer.h
Go to the documentation of this file.
1
/* -*- c++ -*- */
2
/* Copyright 2015-2016 Free Software Foundation, Inc.
3
*
4
* This file is part of GNU Radio
5
*
6
* SPDX-License-Identifier: GPL-3.0-or-later
7
*
8
*/
9
10
#ifndef INCLUDED_DIGITAL_HEADER_BUFFER_H
11
#define INCLUDED_DIGITAL_HEADER_BUFFER_H
12
13
#include <
gnuradio/digital/api.h
>
14
#include <cstdint>
15
#include <cstdlib>
16
#include <vector>
17
18
namespace
gr
{
19
namespace
digital {
20
21
/*!
22
* \brief Helper class for handling payload headers.
23
* \ingroup packet_operators_blk
24
*
25
* \details
26
*
27
* This class is used by the header format blocks (e.g.,
28
* digital::header_format_default) to make it easier to deal with
29
* payload headers. This class functions in two different ways
30
* depending on if it is used in a transmitter or receiver. When
31
* used in a transmitter, this class helps us build headers out of
32
* the fields of the protocol. When used in a receiver, this class
33
* helps us parse the received bits into the protocol's fields.
34
*
35
* This page describes how to work with the different modes,
36
* transmit or receive. The class is instructed as to which mode
37
* it is in by how the constructor is called. If the constructor
38
* is passed a valid array (non NULL), then it is in transmit mode
39
* and will pack this buffer with the header fields. If that
40
* buffer is NULL, the object is in receive mode.
41
*
42
* \section header_buffer_tx Transmit Mode
43
*
44
* When passed a valid buffer in the constructor, this object is in
45
* transmit mode. We can then use the add_field[N] functions to
46
* add new fields to this header. The buffer MUST be large enough
47
* to hold the full header. As this class is meant to work mostly
48
* with the digital::header_format_default and child
49
* classes, the header length can be read from
50
* digital::header_format_default::header_nbytes().
51
*
52
* Each field is a specific length of 8, 16, 32, or 64 bits that
53
* are to be transmitted in network byte order. We can adjust the
54
* direction of the bytes by setting the byte-swap flag, \p bs, to
55
* true or false.
56
*
57
* The length argument (\p len) for all add_field[N] calls is the
58
* number of bytes actually accounted for in the data
59
* structure. Often, we would use the full size of the field,
60
* which is sizeof(dtype), and the add_field[N] call defaults to
61
* len=N. Occasionally, we may need to use fewer bytes than
62
* actually represented by the data type. An example would be the
63
* access code used in the header_format_default, which is a
64
* uint64_t type but may have fewer bytes used in the actual
65
* access code.
66
*
67
* The function that calls this class is expected to handle the
68
* memory handling of the buffer -- both allocating and
69
* deallocating.
70
*
71
* As simple example of using this class in transmit mode:
72
*
73
* \verbatim
74
volk::vector<uint8_t> buffer(header_nbytes());
75
76
header_buffer hdr(buffer);
77
hdr.add_field64(sync_word, sync_word_len);
78
hdr.add_field16(payload_length);
79
hdr.add_field8(header_flags);
80
hdr.add_field8(header_options);
81
82
// Do something with the header
83
\endverbatim
84
*
85
* In this example, the header contains four fields:
86
*
87
* \verbatim
88
|0 15|16 23|24 31|
89
| sync word |
90
| |
91
| length | flags | options |
92
\endverbatim
93
*
94
* The sync word can be up to 64-bits, but the add_field64 is also
95
* passed the number of actual bytes in the sync word and so could
96
* be fewer.
97
*
98
* \section header_buffer_rx Receive Mode
99
*
100
* In receive mode, we build up the header as bits are received by
101
* inserting them with insert_bit. We can find out how long the
102
* current header is, in bits, using the call to length(). If the
103
* header is of the appropriate length, we can then start
104
* extracting the fields from it. When we are done with the
105
* current header, call clear() to reset the internal buffer to
106
* empty, which will mean that length() returns 0.
107
*
108
* The header fields are extracted using the extract_field[N]
109
* functions. Like the add_field[N] functions, we specify the size
110
* (in bits) of the field we are extracting. We pass this function
111
* the bit-position of the expected field in the received header
112
* buffer. The extract_field[N] assumes that the number of bits
113
* for the field is N, but we can tell the function to use fewer
114
* bits if we want. Setting the length parameter of these
115
* functions greater than N is illegal, and it will throw an
116
* error.
117
*
118
* For example, given a header of | length | seq. num. | where the
119
* length is 16 bits and the sequence number is 32 bits, we would
120
* use:
121
*
122
* \verbatim
123
uint16_t len = d_hdr_reg.extract_field16(0);
124
uint32_t seq = d_hdr_reg.extract_field32(16);
125
\endverbatim
126
*
127
* The extract_field functions are specific to data types of the
128
* field and the number of bits for each field is inferred by the
129
* data type. So extract_field16 assumes we want all 16 bits in
130
* the field represented.
131
*
132
* Some headers have fields that are not standard sizes of
133
* integers, like a 1 bit, 4 bit, or even 12 bit fields. We can
134
* ask for fewer bits for each field. say:
135
*
136
* \verbatim
137
|0 15|16 19|20 31|
138
| len | flags | options |
139
\endverbatim
140
*
141
* We would use the following extraction functions:
142
*
143
* \verbatim
144
uint16_t len = d_hdr_reg.extract_field16(0);
145
uint8_t flags = d_hdr_reg.extract_field8(16, 4);
146
uint16_t opts = d_hdr_reg.extract_field16(20, 12);
147
\endverbatim
148
*
149
* \sa header_format_default
150
* \sa header_format_counter
151
* \sa header_format_crc
152
*/
153
class
DIGITAL_API
header_buffer
154
{
155
private
:
156
size_t
d_offset;
157
uint8_t* d_buffer;
158
159
std::vector<bool> d_input;
160
161
public
:
162
/*!
163
* Create a header buffer object with a pre-allocated buffer, \p
164
* buffer, to hold the formatted header data.
165
*
166
* If \p buffer is set to NULL, then this object is in receive
167
* mode meant to receive bits from an incoming data stream and
168
* provide the ability to extract fields. In this mode, calls to
169
* add_field are invalid and will be nops.
170
*/
171
header_buffer
(uint8_t*
buffer
= NULL);
172
173
/*!
174
* Class destructor.
175
*/
176
~header_buffer
();
177
178
/*!
179
* Clears the header.
180
*
181
* In transmit mode, this resets the current offset so new
182
* add_field functions start adding data to the start of the
183
* buffer.
184
*
185
* In receive mode, this clears the buffer that we have inserted
186
* bits in to.
187
*/
188
void
clear
();
189
190
191
/*!
192
* In transmit mode, this returns the length of the data in
193
* the buffer (not the allocated buffer length).
194
*
195
* In receiving mode, this returns the current length in bits of
196
* the received header.
197
*/
198
size_t
length
()
const
;
199
200
/*!
201
* Returns a constant pointer to the buffer.
202
*/
203
const
uint8_t*
header
()
const
;
204
205
/*!
206
* Add an 8-bit field to the header.
207
*
208
* \param data The 8-bit data item.
209
* \param len Length (in bits) of \p data.
210
* \param bs Set to 'true' to byte swap the data.
211
*/
212
void
add_field8
(uint8_t data,
int
len = 8,
bool
bs =
false
);
213
214
/*!
215
* Add an 16-bit field to the header.
216
*
217
* \param data The 16-bit data item.
218
* \param len Length (in bits) of \p data.
219
* \param bs Set to 'true' to byte swap the data.
220
*/
221
void
add_field16
(uint16_t data,
int
len = 16,
bool
bs =
false
);
222
223
/*!
224
* Add an 32-bit field to the header.
225
*
226
* \param data The 32-bit data item.
227
* \param len Length (in bits) of \p data.
228
* \param bs Set to 'true' to byte swap the data.
229
*/
230
void
add_field32
(uint32_t data,
int
len = 32,
bool
bs =
false
);
231
232
/*!
233
* Add an 64-bit field to the header.
234
*
235
* \param data The 64-bit data item.
236
* \param len Length (in bits) of \p data.
237
* \param bs Set to 'true' to byte swap the data.
238
*/
239
void
add_field64
(uint64_t data,
int
len = 64,
bool
bs =
false
);
240
241
242
/*****************************************************
243
* Receive mode to build a header from bits *
244
*****************************************************/
245
246
/*!
247
* Insert a new bit on the back of the input buffer. This
248
* function is used in receive mode to add new bits as they are
249
* received for later use of the extract_field functions.
250
*
251
* \param bit New bit to add.
252
*/
253
void
insert_bit
(
int
bit);
254
255
256
/*!
257
* Returns a field in the packet header.
258
*
259
* \param pos Bit position of the start of the field.
260
* \param len The number of bits in the field.
261
* \param bs Set to 'true' to byte swap the data.
262
* \param lsb_first Set to 'true' to read field encoded as least significant bit first
263
*/
264
template
<
class
T>
265
T
extract_field
(
int
pos,
266
int
len = 8 *
sizeof
(T),
267
bool
bs =
false
,
268
bool
lsb_first =
false
);
269
270
/*!
271
* Returns up to an 8-bit field in the packet header.
272
*
273
* \param pos Bit position of the start of the field.
274
* \param len The number of bits in the field.
275
* \param bs Set to 'true' to byte swap the data.
276
* \param lsb_first Set to 'true' to read field encoded as least significant bit first
277
*/
278
uint8_t
extract_field8
(
int
pos,
int
len = 8,
bool
bs =
false
,
bool
lsb_first =
false
)
279
{
280
return
extract_field<uint8_t>(pos, len, bs, lsb_first);
281
};
282
// constexpr auto& extract_field8 = extract_field<uint8_t>;
283
/*!
284
* Returns up to a 16-bit field in the packet header.
285
*
286
* \param pos Bit position of the start of the field.
287
* \param len The number of bits in the field.
288
* \param bs Set to 'true' to byte swap the data.
289
* \param lsb_first Set to 'true' to read field encoded as least significant bit first
290
*/
291
uint16_t
292
extract_field16
(
int
pos,
int
len = 16,
bool
bs =
false
,
bool
lsb_first =
false
)
293
{
294
return
extract_field<uint16_t>(pos, len, bs, lsb_first);
295
};
296
297
/*!
298
* Returns up to a 32-bit field in the packet header.
299
*
300
* \param pos Bit position of the start of the field.
301
* \param len The number of bits in the field.
302
* \param bs Set to 'true' to byte swap the data.
303
* \param lsb_first Set to 'true' to read field encoded as least significant bit first
304
*/
305
uint32_t
306
extract_field32
(
int
pos,
int
len = 32,
bool
bs =
false
,
bool
lsb_first =
false
)
307
{
308
return
extract_field<uint32_t>(pos, len, bs, lsb_first);
309
};
310
311
/*!
312
* Returns up to a 64-bit field in the packet header.
313
*
314
* \param pos Bit position of the start of the field.
315
* \param len The number of bits in the field.
316
* \param bs Set to 'true' to byte swap the data.
317
* \param lsb_first Set to 'true' to read field encoded as least significant bit first
318
*/
319
uint64_t
320
extract_field64
(
int
pos,
int
len = 64,
bool
bs =
false
,
bool
lsb_first =
false
)
321
{
322
return
extract_field<uint64_t>(pos, len, bs, lsb_first);
323
};
324
};
325
326
}
// namespace digital
327
}
// namespace gr
328
329
#endif
/* INCLUDED_DIGITAL_HEADER_BUFFER_H */
gr::buffer
Single writer, multiple reader fifo.
Definition
buffer.h:67
gr::digital::header_buffer
Helper class for handling payload headers.
Definition
header_buffer.h:154
gr::digital::header_buffer::insert_bit
void insert_bit(int bit)
gr::digital::header_buffer::extract_field8
uint8_t extract_field8(int pos, int len=8, bool bs=false, bool lsb_first=false)
Definition
header_buffer.h:278
gr::digital::header_buffer::add_field8
void add_field8(uint8_t data, int len=8, bool bs=false)
gr::digital::header_buffer::extract_field16
uint16_t extract_field16(int pos, int len=16, bool bs=false, bool lsb_first=false)
Definition
header_buffer.h:292
gr::digital::header_buffer::extract_field64
uint64_t extract_field64(int pos, int len=64, bool bs=false, bool lsb_first=false)
Definition
header_buffer.h:320
gr::digital::header_buffer::add_field64
void add_field64(uint64_t data, int len=64, bool bs=false)
gr::digital::header_buffer::add_field16
void add_field16(uint16_t data, int len=16, bool bs=false)
gr::digital::header_buffer::add_field32
void add_field32(uint32_t data, int len=32, bool bs=false)
gr::digital::header_buffer::header_buffer
header_buffer(uint8_t *buffer=NULL)
gr::digital::header_buffer::extract_field
T extract_field(int pos, int len=8 *sizeof(T), bool bs=false, bool lsb_first=false)
gr::digital::header_buffer::length
size_t length() const
gr::digital::header_buffer::~header_buffer
~header_buffer()
gr::digital::header_buffer::extract_field32
uint32_t extract_field32(int pos, int len=32, bool bs=false, bool lsb_first=false)
Definition
header_buffer.h:306
gr::digital::header_buffer::header
const uint8_t * header() const
gr::digital::header_buffer::clear
void clear()
api.h
DIGITAL_API
#define DIGITAL_API
Definition
gr-digital/include/gnuradio/digital/api.h:18
gr
GNU Radio logging wrapper.
Definition
basic_block.h:29
gr-digital
include
gnuradio
digital
header_buffer.h
Generated by
1.9.8