GNU Radio's BLUETOOTH Package
packet.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright 2013 Christopher D. Kilgour
4 * Copyright 2008, 2009 Dominic Spill, Michael Ossmann
5 * Copyright 2007 Dominic Spill
6 * Copyright 2005, 2006 Free Software Foundation, Inc.
7 *
8 * This file is part of gr-bluetooth
9 *
10 * This is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This software is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this software; see the file COPYING. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street,
23 * Boston, MA 02110-1301, USA.
24 */
25
26
27#ifndef INCLUDED_GR_BLUETOOTH_PACKET_H
28#define INCLUDED_GR_BLUETOOTH_PACKET_H
29
30#include <bluetooth/api.h>
31#include <gnuradio/sync_block.h>
32#include <string>
33
34namespace gr {
35 namespace bluetooth {
36
38 {
39 friend class classic_packet;
40 friend class classic_packet_impl;
41 friend class le_packet;
42 friend class le_packet_impl;
43
44 public:
45 typedef enum {
50 } air_format;
51
52 typedef std::shared_ptr<packet> sptr;
53
54 private:
55 air_format d_format;
56 double d_freq;
57 int d_length; /* number of symbols */
58
59 static const int MAX_SYMBOLS = 3125; /* maximum number of symbols */
60
61 /* the raw symbol stream, one bit per char */
62 //FIXME maybe this should be a vector so we can grow it only to the size
63 //needed and later shrink it if we find we have more symbols than necessary
64 char d_symbols[MAX_SYMBOLS];
65
66 /* packet type */
67 int d_packet_type;
68
69 /* payload length: the total length of the asynchronous data in bytes.
70 * This does not include the length of synchronous data, such as the voice
71 * field of a DV packet.
72 * If there is a payload header, this payload length is payload body length
73 * (the length indicated in the payload header's length field) plus
74 * d_payload_header_length plus 2 bytes CRC (if present).
75 */
76 int d_payload_length;
77
78 /* The actual payload data in host format
79 * Ready for passing to wireshark
80 * 2744 is the maximum length, but most packets are shorter.
81 * Dynamic allocation would probably be better in the long run but is
82 * problematic in the short run.
83 */
84 char d_payload[2744];
85
86 /* is the packet whitened? */
87 bool d_whitened;
88
89 bool d_have_payload;
90
91 public:
92 // -------------------------------------------------------------------
93
94 packet() {}
95 packet(char *stream, int length, double freq=0.0);
96 virtual ~packet( ) {}
97
98 // -------------------------------------------------------------------
99
100 /* whitening data, both classic and LE use the same whitening LFSR */
101 static const uint8_t WHITENING_DATA[127];
102
103 static int sniff_packet(char *stream, int stream_length, double freq, air_format& fmt);
104
105 /* Reverse the bits in a byte */
106 static uint8_t reverse(char byte);
107
108 /* Convert from normal bytes to one-LSB-per-byte format */
109 static void convert_to_grformat(uint8_t input, uint8_t *output);
110
111 /* Convert some number of bits of an air order array to a host order integer */
112 static uint8_t air_to_host8(char *air_order, int bits);
113 static uint16_t air_to_host16(char *air_order, int bits);
114 static uint32_t air_to_host32(char *air_order, int bits);
115 // hmmm, maybe these should have pointer output so they can be overloaded
116
117 /* Convert some number of bits in a host order integer to an air order array */
118 static void host_to_air(uint8_t host_order, char *air_order, int bits);
119
120 // -------------------------------------------------------------------
121
122 /* is the packet whitened? */
124
125 /* set the packet's whitened flag */
126 void set_whitened(bool whitened);
127
128 /* Retrieve the length of the payload data */
130
131 /* have we decoded the payload yet? */
133
134 int get_type();
135
136 /* decode the whole packet */
137 void decode();
138
139 // -------------------------------------------------------------------
140
141 /* decode the packet header */
142 virtual bool decode_header() = 0;
143
144 /* decode the packet header */
145 virtual void decode_payload() = 0;
146
147 /* print packet information */
148 virtual void print() = 0;
149
150 /* format payload for tun interface */
151 virtual char *tun_format() = 0;
152
153 /* check to see if the packet has a header */
154 virtual bool header_present() = 0;
155
156 virtual int get_channel() = 0;
157 };
158
159 /*!
160 * \brief <+description of block+>
161 * \ingroup gr_bluetooth
162 */
163 class BLUETOOTH_API classic_packet : virtual public packet
164 {
165 private:
166 int d_channel;
167
168 public:
169 typedef std::shared_ptr<classic_packet> sptr;
170
171 /*!
172 * \brief Return a shared_ptr to a new instance of gr::bluetooth::classic_packet.
173 *
174 * To avoid accidental use of raw pointers, gr::bluetooth::classic_packet's
175 * constructor is in a private implementation
176 * class. gr::bluetooth::classic_packet::make is the public interface for
177 * creating new instances.
178 */
179 static sptr make(char *stream, int length);
180
181 /* construct with known CLKN and channel */
182 static sptr make(char *stream, int length, uint32_t clkn, double freq);
183
184 /* minimum header bit errors to indicate that this is an ID packet */
185 static const int ID_THRESHOLD = 5;
186
188
189 /* index into whitening data array */
190 static const uint8_t INDICES[64];
191
192 /* lookup table for preamble hamming distance */
193 static const uint8_t PREAMBLE_DISTANCE[32];
194
195 /* lookup table for barker hamming distance */
196 static const uint8_t BARKER_DISTANCE[128];
197
198 /* string representations of classic packet type */
199 static const std::string TYPE_NAMES[16];
200
201 /* native (local) clock */
202 uint32_t d_clkn;
203
204 /* search a symbol stream to find a packet, return index */
205 static int sniff_ac(char *stream, int stream_length);
206
207 /* Error correction coding for Access Code */
208 static uint8_t *lfsr(uint8_t *data, int length, int k, uint8_t *g);
209
210 /* Generate Access Code from an LAP */
211 static uint8_t *acgen(int LAP);
212
213 /* Decode 1/3 rate FEC, three like symbols in a row */
214 static bool unfec13(char *input, char *output, int length);
215
216 /* Decode 2/3 rate FEC, a (15,10) shortened Hamming code */
217 static char *unfec23(char *input, int length);
218
219 /* When passed 10 bits of data this returns a pointer to a 5 bit hamming code */
220 //static char *fec23gen(char *data);
221
222 /* Create an Access Code from LAP and check it against stream */
223 static bool check_ac(char *stream, int LAP);
224
225 /* Create the 16bit CRC for classic packet payloads - input air order stream */
226 static uint16_t crcgen(char *payload, int length, int UAP);
227
228 /* extract UAP by reversing the HEC computation */
229 static int UAP_from_hec(uint16_t data, uint8_t hec);
230
231 /* check if the classic_packet's CRC is correct for a given clock (CLK1-6) */
232 virtual int crc_check(int clock) = 0;
233
234 /* decode the classic packet header */
235 virtual bool decode_header() = 0;
236
237 /* decode the classic packet header */
238 virtual void decode_payload() = 0;
239
240 /* print classic packet information */
241 virtual void print() = 0;
242
243 /* format payload for tun interface */
244 virtual char *tun_format() = 0;
245
246 /* return the classic packet's LAP */
247 virtual uint32_t get_LAP() = 0;
248
249 /* return the classic packet's UAP */
250 virtual uint8_t get_UAP() = 0;
251
252 /* set the classic packet's UAP */
253 virtual void set_UAP(uint8_t UAP) = 0;
254
255 /* set the classic packet's NAP */
256 virtual void set_NAP(uint16_t NAP) = 0;
257
258 /* return the classic_packet's clock (CLK1-27) */
259 virtual uint32_t get_clock() = 0;
260
261 /* set the classic_packet's clock */
262 virtual void set_clock(uint32_t clk6, bool have27) = 0;
263
264 /* try a clock value (CLK1-6) to unwhiten classic_packet header,
265 * sets resultant d_packet_type and d_UAP, returns UAP.
266 */
267 virtual uint8_t try_clock(int clock) = 0;
268
269 /* check to see if the classic packet has a header */
270 virtual bool header_present() = 0;
271
272 /* extract LAP from FHS payload */
273 virtual uint32_t lap_from_fhs() = 0;
274
275 /* extract UAP from FHS payload */
276 virtual uint8_t uap_from_fhs() = 0;
277
278 /* extract NAP from FHS payload */
279 virtual uint16_t nap_from_fhs() = 0;
280
281 /* extract clock from FHS payload */
282 virtual uint32_t clock_from_fhs() = 0;
283
284 int get_channel( ) { return d_channel; }
285 };
286
287#define LE_MAX_PDU_OCTETS 39
288#define LE_MAX_OCTETS (1+4+LE_MAX_PDU_OCTETS+3)
289#define LE_MAX_SYMBOLS (8*LE_MAX_OCTETS)
290
291 class BLUETOOTH_API le_packet : virtual public packet
292 {
293 public:
294 static const unsigned MAX_PDU_OCTETS = LE_MAX_PDU_OCTETS;
295 static const unsigned MAX_OCTETS = LE_MAX_OCTETS;
296 static const unsigned MAX_SYMBOLS = LE_MAX_SYMBOLS;
297
298 typedef std::shared_ptr<le_packet> sptr;
299
300 static sptr make(char *stream, int length, double freq=0.0);
301 static int freq2chan(const double freq);
302 static int chan2index(const int chan);
303 static int freq2index(const double freq);
304
305 /* whitening sequence indices */
306 static const uint8_t INDICES[40];
307
308 /* lookup table for preamble hamming distance */
309 static const uint8_t PREAMBLE_DISTANCE[512];
310
311 /* lookup table for access address */
312 static const uint8_t ACCESS_ADDRESS_DISTANCE_0[256];
313 static const uint8_t ACCESS_ADDRESS_DISTANCE_1[256];
314 static const uint8_t ACCESS_ADDRESS_DISTANCE_2[256];
315 static const uint8_t ACCESS_ADDRESS_DISTANCE_3[256];
316
317 /* lookup table for header hamming distances */
318 static const uint8_t ACCESS_HEADER_DISTANCE_LSB[256];
319 static const uint8_t ACCESS_HEADER_DISTANCE_MSB[256];
320 static const uint8_t DATA_HEADER_DISTANCE_LSB[256];
321 static const uint8_t DATA_HEADER_DISTANCE_MSB[256];
322
323 static int sniff_aa(char *stream, int stream_length, double freq);
324
325 /* decode the packet header */
326 virtual bool decode_header() = 0;
327
328 /* decode the packet header */
329 virtual void decode_payload() = 0;
330
331 /* print packet information */
332 virtual void print() = 0;
333
334 /* format payload for tun interface */
335 virtual char *tun_format() = 0;
336
337 /* check to see if the packet has a header */
338 virtual bool header_present() = 0;
339
340 /* return the low-energy packet's AA */
341 virtual uint32_t get_AA() = 0;
342
343 virtual int get_channel( ) = 0;
344 };
345
346 } // namespace bluetooth
347} // namespace gr
348
349#endif /* INCLUDED_GR_BLUETOOTH_PACKET_H */
350
#define BLUETOOTH_API
Definition api.h:19
static const uint8_t INDICES[64]
Definition packet.h:190
virtual uint32_t clock_from_fhs()=0
static int sniff_ac(char *stream, int stream_length)
virtual void set_UAP(uint8_t UAP)=0
virtual int crc_check(int clock)=0
int get_channel()
Definition packet.h:284
static bool unfec13(char *input, char *output, int length)
static bool check_ac(char *stream, int LAP)
static const uint8_t PREAMBLE_DISTANCE[32]
Definition packet.h:193
virtual uint32_t lap_from_fhs()=0
static const std::string TYPE_NAMES[16]
Definition packet.h:199
std::shared_ptr< classic_packet > sptr
Definition packet.h:169
uint32_t d_clkn
Definition packet.h:202
virtual uint32_t get_LAP()=0
virtual uint8_t get_UAP()=0
virtual char * tun_format()=0
virtual uint16_t nap_from_fhs()=0
static sptr make(char *stream, int length)
Return a shared_ptr to a new instance of gr::bluetooth::classic_packet.
virtual void decode_payload()=0
static const uint8_t BARKER_DISTANCE[128]
Definition packet.h:196
static uint8_t * lfsr(uint8_t *data, int length, int k, uint8_t *g)
static sptr make(char *stream, int length, uint32_t clkn, double freq)
static uint16_t crcgen(char *payload, int length, int UAP)
static char * unfec23(char *input, int length)
virtual uint32_t get_clock()=0
static int UAP_from_hec(uint16_t data, uint8_t hec)
virtual uint8_t uap_from_fhs()=0
static const int ID_THRESHOLD
Definition packet.h:185
virtual void set_clock(uint32_t clk6, bool have27)=0
virtual bool header_present()=0
virtual bool decode_header()=0
virtual void set_NAP(uint16_t NAP)=0
virtual uint8_t try_clock(int clock)=0
static const int SYMBOLS_PER_BASIC_RATE_ACCESS_CODE
Definition packet.h:187
static uint8_t * acgen(int LAP)
static int freq2index(const double freq)
static int freq2chan(const double freq)
virtual bool header_present()=0
virtual char * tun_format()=0
static const unsigned MAX_PDU_OCTETS
Definition packet.h:294
static const uint8_t PREAMBLE_DISTANCE[512]
Definition packet.h:309
static const unsigned MAX_OCTETS
Definition packet.h:295
virtual void print()=0
virtual uint32_t get_AA()=0
std::shared_ptr< le_packet > sptr
Definition packet.h:298
static const uint8_t ACCESS_HEADER_DISTANCE_MSB[256]
Definition packet.h:319
static const unsigned MAX_SYMBOLS
Definition packet.h:296
static const uint8_t ACCESS_ADDRESS_DISTANCE_3[256]
Definition packet.h:315
virtual void decode_payload()=0
virtual bool decode_header()=0
static const uint8_t DATA_HEADER_DISTANCE_MSB[256]
Definition packet.h:321
static const uint8_t INDICES[40]
Definition packet.h:306
static int sniff_aa(char *stream, int stream_length, double freq)
static const uint8_t ACCESS_ADDRESS_DISTANCE_2[256]
Definition packet.h:314
static const uint8_t ACCESS_ADDRESS_DISTANCE_1[256]
Definition packet.h:313
static const uint8_t ACCESS_ADDRESS_DISTANCE_0[256]
Definition packet.h:312
static const uint8_t DATA_HEADER_DISTANCE_LSB[256]
Definition packet.h:320
virtual int get_channel()=0
static sptr make(char *stream, int length, double freq=0.0)
static const uint8_t ACCESS_HEADER_DISTANCE_LSB[256]
Definition packet.h:318
static int chan2index(const int chan)
virtual bool header_present()=0
friend class le_packet_impl
Definition packet.h:42
static uint8_t air_to_host8(char *air_order, int bits)
std::shared_ptr< packet > sptr
Definition packet.h:52
friend class le_packet
Definition packet.h:41
packet(char *stream, int length, double freq=0.0)
virtual ~packet()
Definition packet.h:96
static uint32_t air_to_host32(char *air_order, int bits)
packet()
Definition packet.h:94
friend class classic_packet_impl
Definition packet.h:40
friend class classic_packet
Definition packet.h:39
static int sniff_packet(char *stream, int stream_length, double freq, air_format &fmt)
static uint8_t reverse(char byte)
air_format
Definition packet.h:45
@ UNKNOWN
Definition packet.h:46
@ CLASSIC
Definition packet.h:47
@ LOW_ENERGY
Definition packet.h:48
@ NUM_BTAF
Definition packet.h:49
static uint16_t air_to_host16(char *air_order, int bits)
static const uint8_t WHITENING_DATA[127]
Definition packet.h:101
virtual char * tun_format()=0
static void convert_to_grformat(uint8_t input, uint8_t *output)
virtual int get_channel()=0
virtual bool decode_header()=0
void set_whitened(bool whitened)
static void host_to_air(uint8_t host_order, char *air_order, int bits)
virtual void print()=0
virtual void decode_payload()=0
Definition multi_block.h:34
Definition multi_block.h:33
#define LE_MAX_PDU_OCTETS
Definition packet.h:287
#define LE_MAX_OCTETS
Definition packet.h:288
#define LE_MAX_SYMBOLS
Definition packet.h:289