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