xref: /libbtbb/lib/src/bluetooth_le_packet.c (revision c7ad541565378070ac837c1404475f2fcbb680b0)
1 /* -*- c -*- */
2 /*
3  * Copyright 2007 - 2012 Mike Ryan, Dominic Spill, Michael Ossmann
4  * Copyright 2005, 2006 Free Software Foundation, Inc.
5  *
6  * This file is part of libbtbb
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with libbtbb; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "btbb.h"
29 #include "bluetooth_le_packet.h"
30 #include <ctype.h>
31 #include <string.h>
32 
33 /* string representations of advertising packet type */
34 static const char *ADV_TYPE_NAMES[] = {
35 	"ADV_IND", "ADV_DIRECT_IND", "ADV_NONCONN_IND", "SCAN_REQ",
36 	"SCAN_RSP", "CONNECT_REQ", "ADV_SCAN_IND",
37 };
38 
39 /* source clock accuracy in a connect packet */
40 static const char *CONNECT_SCA[] = {
41 	"251 ppm to 500 ppm", "151 ppm to 250 ppm", "101 ppm to 150 ppm",
42 	"76 ppm to 100 ppm", "51 ppm to 75 ppm", "31 ppm to 50 ppm",
43 	"21 ppm to 30 ppm", "0 ppm to 20 ppm",
44 };
45 
46 // count of objects in an array, shamelessly stolen from Chrome
47 #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
48 
49 static uint8_t count_bits(uint32_t n)
50 {
51 	uint8_t i = 0;
52 	for (i = 0; n != 0; i++)
53 		n &= n - 1;
54 	return i;
55 }
56 
57 static int aa_access_channel_off_by_one(const uint32_t aa) {
58 	int retval = 0;
59 	if(count_bits(aa ^ LE_ADV_AA) == 1) {
60 		retval = 1;
61 	}
62 	return retval;
63 }
64 
65 /*
66  * A helper function for filtering bogus packets on data channels.
67  *
68  * If a candidate capture packet is random noise we would expect its
69  * Access Address to be a randomly distributed 32-bit number.  An
70  * exhaustive software analysis reveals that of 4294967296 possible
71  * 32-bit Access Address values, 2900629660 (67.5%) are acceptable and
72  * 1394337636 (32.5%) are invalid.  This function will identify which
73  * category a candidate Access Address falls into by returning the
74  * number of offenses contained.
75  *
76  * Refer to BT 4.x, Vol 6, Par B, Section 2.1.2.
77  *
78  * The Access Address in data channel packets meet the
79  * following requirements:
80  *  - It shall have no more than six consecutive zeros or ones.
81  *  - It shall not be the advertising channel packets’ Access Address.
82  *  - It shall not be a sequence that differs from the advertising channel packets’
83  *    Access Address by only one bit.
84  *  - It shall not have all four octets equal.
85  *  - It shall have no more than 24 transitions.
86  *  - It shall have a minimum of two transitions in the most significant six bits.
87  */
88 static int aa_data_channel_offenses(const uint32_t aa) {
89 	int retval = 0, transitions = 0;
90 	unsigned shift, odd = (unsigned) (aa & 1);
91 	uint8_t aab3, aab2, aab1, aab0 = (uint8_t) (aa & 0xff);
92 
93 	const uint8_t EIGHT_BIT_TRANSITIONS_EVEN[256] = {
94 		0, 2, 2, 2, 2, 4, 2, 2, 2, 4, 4, 4, 2, 4, 2, 2,
95 		2, 4, 4, 4, 4, 6, 4, 4, 2, 4, 4, 4, 2, 4, 2, 2,
96 		2, 4, 4, 4, 4, 6, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4,
97 		2, 4, 4, 4, 4, 6, 4, 4, 2, 4, 4, 4, 2, 4, 2, 2,
98 		2, 4, 4, 4, 4, 6, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4,
99 		4, 6, 6, 6, 6, 8, 6, 6, 4, 6, 6, 6, 4, 6, 4, 4,
100 		2, 4, 4, 4, 4, 6, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4,
101 		2, 4, 4, 4, 4, 6, 4, 4, 2, 4, 4, 4, 2, 4, 2, 2,
102 		1, 3, 3, 3, 3, 5, 3, 3, 3, 5, 5, 5, 3, 5, 3, 3,
103 		3, 5, 5, 5, 5, 7, 5, 5, 3, 5, 5, 5, 3, 5, 3, 3,
104 		3, 5, 5, 5, 5, 7, 5, 5, 5, 7, 7, 7, 5, 7, 5, 5,
105 		3, 5, 5, 5, 5, 7, 5, 5, 3, 5, 5, 5, 3, 5, 3, 3,
106 		1, 3, 3, 3, 3, 5, 3, 3, 3, 5, 5, 5, 3, 5, 3, 3,
107 		3, 5, 5, 5, 5, 7, 5, 5, 3, 5, 5, 5, 3, 5, 3, 3,
108 		1, 3, 3, 3, 3, 5, 3, 3, 3, 5, 5, 5, 3, 5, 3, 3,
109 		1, 3, 3, 3, 3, 5, 3, 3, 1, 3, 3, 3, 1, 3, 1, 1
110 	};
111 
112 	const uint8_t EIGHT_BIT_TRANSITIONS_ODD[256] = {
113 		1, 1, 3, 1, 3, 3, 3, 1, 3, 3, 5, 3, 3, 3, 3, 1,
114 		3, 3, 5, 3, 5, 5, 5, 3, 3, 3, 5, 3, 3, 3, 3, 1,
115 		3, 3, 5, 3, 5, 5, 5, 3, 5, 5, 7, 5, 5, 5, 5, 3,
116 		3, 3, 5, 3, 5, 5, 5, 3, 3, 3, 5, 3, 3, 3, 3, 1,
117 		3, 3, 5, 3, 5, 5, 5, 3, 5, 5, 7, 5, 5, 5, 5, 3,
118 		5, 5, 7, 5, 7, 7, 7, 5, 5, 5, 7, 5, 5, 5, 5, 3,
119 		3, 3, 5, 3, 5, 5, 5, 3, 5, 5, 7, 5, 5, 5, 5, 3,
120 		3, 3, 5, 3, 5, 5, 5, 3, 3, 3, 5, 3, 3, 3, 3, 1,
121 		2, 2, 4, 2, 4, 4, 4, 2, 4, 4, 6, 4, 4, 4, 4, 2,
122 		4, 4, 6, 4, 6, 6, 6, 4, 4, 4, 6, 4, 4, 4, 4, 2,
123 		4, 4, 6, 4, 6, 6, 6, 4, 6, 6, 8, 6, 6, 6, 6, 4,
124 		4, 4, 6, 4, 6, 6, 6, 4, 4, 4, 6, 4, 4, 4, 4, 2,
125 		2, 2, 4, 2, 4, 4, 4, 2, 4, 4, 6, 4, 4, 4, 4, 2,
126 		4, 4, 6, 4, 6, 6, 6, 4, 4, 4, 6, 4, 4, 4, 4, 2,
127 		2, 2, 4, 2, 4, 4, 4, 2, 4, 4, 6, 4, 4, 4, 4, 2,
128 		2, 2, 4, 2, 4, 4, 4, 2, 2, 2, 4, 2, 2, 2, 2, 0
129 	};
130 
131 	transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab0] : EIGHT_BIT_TRANSITIONS_EVEN[aab0] );
132 	odd = (unsigned) (aab0 & 0x80);
133 	aab1 = (uint8_t) (aa >> 8);
134 	transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab1] : EIGHT_BIT_TRANSITIONS_EVEN[aab1] );
135 	odd = (unsigned) (aab1 & 0x80);
136 	aab2 = (uint8_t) (aa >> 16);
137 	transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab2] : EIGHT_BIT_TRANSITIONS_EVEN[aab2] );
138 	odd = (unsigned) (aab2 & 0x80);
139 	aab3 = (uint8_t) (aa >> 24);
140 	transitions += (odd ? EIGHT_BIT_TRANSITIONS_ODD[aab3] : EIGHT_BIT_TRANSITIONS_EVEN[aab3] );
141 
142 	/* consider excessive transitions as offenses */
143 	if (transitions > 24) {
144 		retval += (transitions - 24);
145 	}
146 
147 	const uint8_t AA_MSB6_ALLOWED[64] = {
148 		0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
149 		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
150 		0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
151 		0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0
152 	};
153 
154 	/* consider excessive transitions in the 6 MSBs as an offense */
155 	retval += (1 - AA_MSB6_ALLOWED[aab3>>2]);
156 
157 	/* consider all bytes as being equal an offense */
158 	retval += (((aab0 == aab1) && (aab0 == aab2) && (aab0 == aab3)) ? 1 : 0);
159 
160 	/* access-channel address and off-by-ones are illegal */
161 	retval += ((aa == LE_ADV_AA) ? 1 : 0);
162 	retval += aa_access_channel_off_by_one(aa);
163 
164 	/* inspect nibble triples for insufficient bit transitions */
165 	for(shift=0; shift<=20; shift+=4) {
166 		uint16_t twelvebits = (uint16_t) ((aa >> shift) & 0xfff);
167 		switch( twelvebits ) {
168 			/* seven consecutive zeroes */
169 		case 0x080: case 0x180: case 0x280: case 0x380: case 0x480:
170 		case 0x580: case 0x680: case 0x780: case 0x880: case 0x980:
171 		case 0xa80: case 0xb80: case 0xc80: case 0xd80: case 0xe80:
172 		case 0xf80: case 0x101: case 0x301: case 0x501: case 0x701:
173 		case 0x901: case 0xb01: case 0xd01: case 0xf01: case 0x202:
174 		case 0x602: case 0xa02: case 0xe02: case 0x203: case 0x603:
175 		case 0xa03: case 0xe03: case 0x404: case 0xc04: case 0x405:
176 		case 0xc05: case 0x406: case 0xc06: case 0x407: case 0xc07:
177 		case 0x808: case 0x809: case 0x80a: case 0x80b: case 0x80c:
178 		case 0x80d: case 0x80e: case 0x80f: case 0x010: case 0x011:
179 		case 0x012: case 0x013: case 0x014: case 0x015: case 0x016:
180 		case 0x017: case 0x018: case 0x019: case 0x01a: case 0x01b:
181 		case 0x01c: case 0x01d: case 0x01e: case 0x01f:
182 			/* eight consecutive zeroes */
183 		case 0x100: case 0x300: case 0x500: case 0x700: case 0x900:
184 		case 0xb00: case 0xd00: case 0xf00: case 0x201: case 0x601:
185 		case 0xa01: case 0xe01: case 0x402: case 0xc02: case 0x403:
186 		case 0xc03: case 0x804: case 0x805: case 0x806: case 0x807:
187 		case 0x008: case 0x009: case 0x00a: case 0x00b: case 0x00c:
188 		case 0x00d: case 0x00e: case 0x00f:
189 			/* nine consecutive zeroes */
190 		case 0xe00: case 0xc01: case 0x802: case 0x803: case 0x004:
191 		case 0x005: case 0x006: case 0x007:
192 			/* ten consecutive zeroes */
193 		case 0x400: case 0xc00: case 0x801: case 0x002: case 0x003:
194 			/* eleven consecutive zeroes */
195 		case 0x800: case 0x001:
196 			/* twelve consecutive zeroes */
197 		case 0x000:
198 			/* seven consecutive ones */
199 		case 0x07f: case 0x0fe: case 0x2fe: case 0x4fe: case 0x6fe:
200 		case 0x8fe: case 0xafe: case 0xcfe: case 0xefe: case 0x1fc:
201 		case 0x5fc: case 0x9fc: case 0xdfc: case 0x1fd: case 0x5fd:
202 		case 0x9fd: case 0xdfd: case 0x3f8: case 0xbf8: case 0x3f9:
203 		case 0xbf9: case 0x3fa: case 0xbfa: case 0x3fb: case 0xbfb:
204 		case 0x7f4: case 0x7f5: case 0x7f6: case 0x7f7: case 0xfe0:
205 			/* eight consecutive ones */
206 		case 0x0ff: case 0x2ff: case 0x4ff: case 0x6ff: case 0x8ff:
207 		case 0xaff: case 0xcff: case 0xeff: case 0x1fe: case 0x5fe:
208 		case 0x9fe: case 0xdfe: case 0x3fc: case 0xbfc: case 0x3fd:
209 		case 0xbfd: case 0x7f8: case 0x7f9: case 0x7fa: case 0x7fb:
210 		case 0xff0: case 0xff1: case 0xff2: case 0xff3: case 0xff4:
211 		case 0xff5: case 0xff6: case 0xff7:
212 			/* nine consecutive ones */
213 		case 0x1ff: case 0x5ff: case 0x9ff: case 0xdff: case 0x3fe:
214 		case 0xbfe: case 0x7fc: case 0x7fd: case 0xff8: case 0xff9:
215 		case 0xffa: case 0xffb:
216 			/* ten consecutive ones */
217 		case 0x3ff: case 0xbff: case 0x7fe: case 0xffc: case 0xffd:
218 			/* eleven consecutive ones */
219 		case 0x7ff: case 0xffe:
220 			/* all ones */
221 		case 0xfff:
222 			retval++;
223 			break;
224 		default:
225 			break;
226 		}
227 	}
228 
229 	return retval;
230 }
231 
232 lell_packet *
233 lell_packet_new(void)
234 {
235 	lell_packet *pkt = (lell_packet *)calloc(1, sizeof(lell_packet));
236 	pkt->refcount = 1;
237 	return pkt;
238 }
239 
240 void
241 lell_packet_ref(lell_packet *pkt)
242 {
243 	pkt->refcount++;
244 }
245 
246 void
247 lell_packet_unref(lell_packet *pkt)
248 {
249 	pkt->refcount--;
250 	if (pkt->refcount == 0)
251 		free(pkt);
252 }
253 
254 static uint8_t le_channel_index(uint16_t phys_channel) {
255 	uint8_t ret;
256 	if (phys_channel == 2402) {
257 		ret = 37;
258 	} else if (phys_channel < 2426) { // 0 - 10
259 		ret = (phys_channel - 2404) / 2;
260 	} else if (phys_channel == 2426) {
261 		ret = 38;
262 	} else if (phys_channel < 2480) { // 11 - 36
263 		ret = 11 + (phys_channel - 2428) / 2;
264 	} else {
265 		ret = 39;
266 	}
267 	return ret;
268 }
269 
270 void lell_allocate_and_decode(const uint8_t *stream, uint16_t phys_channel, uint32_t clk100ns, lell_packet **pkt)
271 {
272 	*pkt = lell_packet_new( );
273 	memcpy((*pkt)->symbols, stream, MAX_LE_SYMBOLS);
274 
275 	(*pkt)->channel_idx = le_channel_index(phys_channel);
276 	(*pkt)->channel_k = (phys_channel-2402)/2;
277 	(*pkt)->clk100ns = clk100ns;
278 
279 	(*pkt)->access_address = 0;
280 	(*pkt)->access_address |= (*pkt)->symbols[0];
281 	(*pkt)->access_address |= (*pkt)->symbols[1] << 8;
282 	(*pkt)->access_address |= (*pkt)->symbols[2] << 16;
283 	(*pkt)->access_address |= (*pkt)->symbols[3] << 24;
284 
285 	if (lell_packet_is_data(*pkt)) {
286 		// data PDU
287 		(*pkt)->length = (*pkt)->symbols[5] & 0x1f;
288 		(*pkt)->access_address_offenses = aa_data_channel_offenses((*pkt)->access_address);
289 		(*pkt)->flags.as_bits.access_address_ok = (*pkt)->access_address_offenses ? 0 : 1;
290 	} else {
291 		// advertising PDU
292 		(*pkt)->length = (*pkt)->symbols[5] & 0x3f;
293 		(*pkt)->adv_type = (*pkt)->symbols[4] & 0xf;
294 		(*pkt)->adv_tx_add = (*pkt)->symbols[4] & 0x40 ? 1 : 0;
295 		(*pkt)->adv_rx_add = (*pkt)->symbols[4] & 0x80 ? 1 : 0;
296 		(*pkt)->flags.as_bits.access_address_ok = ((*pkt)->access_address == 0x8e89bed6);
297 		(*pkt)->access_address_offenses = (*pkt)->flags.as_bits.access_address_ok ? 0 :
298 			(aa_access_channel_off_by_one((*pkt)->access_address) ? 1 : 32);
299 	}
300 }
301 
302 unsigned lell_packet_is_data(const lell_packet *pkt)
303 {
304 	return (unsigned) (pkt->channel_idx < 37);
305 }
306 
307 uint32_t lell_get_access_address(const lell_packet *pkt)
308 {
309 	return pkt->access_address;
310 }
311 
312 unsigned lell_get_access_address_offenses(const lell_packet *pkt)
313 {
314 	return pkt->access_address_offenses;
315 }
316 
317 unsigned lell_get_channel_index(const lell_packet *pkt)
318 {
319 	return pkt->channel_idx;
320 }
321 
322 unsigned lell_get_channel_k(const lell_packet *pkt)
323 {
324 	return pkt->channel_k;
325 }
326 
327 const char * lell_get_adv_type_str(const lell_packet *pkt)
328 {
329 	if (lell_packet_is_data(pkt))
330 		return NULL;
331 	if (pkt->adv_type < COUNT_OF(ADV_TYPE_NAMES))
332 		return ADV_TYPE_NAMES[pkt->adv_type];
333 	return "UNKNOWN";
334 }
335 
336 static void _dump_addr(const char *name, const uint8_t *buf, int offset, int random) {
337 	int i;
338 	printf("    %s%02x", name, buf[offset+5]);
339 	for (i = 4; i >= 0; --i)
340 		printf(":%02x", buf[offset+i]);
341 	printf(" (%s)\n", random ? "random" : "public");
342 }
343 
344 static void _dump_8(const char *name, const uint8_t *buf, int offset) {
345 	printf("    %s%02x (%d)\n", name, buf[offset], buf[offset]);
346 }
347 
348 static void _dump_16(const char *name, const uint8_t *buf, int offset) {
349 	uint16_t val = buf[offset+1] << 8 | buf[offset];
350 	printf("    %s%04x (%d)\n", name, val, val);
351 }
352 
353 static void _dump_24(char *name, const uint8_t *buf, int offset) {
354 	uint32_t val = buf[offset+2] << 16 | buf[offset+1] << 8 | buf[offset];
355 	printf("    %s%06x\n", name, val);
356 }
357 
358 static void _dump_32(const char *name, const uint8_t *buf, int offset) {
359 	uint32_t val = buf[offset+3] << 24 |
360 				   buf[offset+2] << 16 |
361 				   buf[offset+1] << 8 |
362 				   buf[offset+0];
363 	printf("    %s%08x\n", name, val);
364 }
365 
366 static void _dump_uuid(const uint8_t *uuid) {
367 	int i;
368 	for (i = 0; i < 4; ++i)
369 		printf("%02x", uuid[i]);
370 	printf("-");
371 	for (i = 4; i < 6; ++i)
372 		printf("%02x", uuid[i]);
373 	printf("-");
374 	for (i = 6; i < 8; ++i)
375 		printf("%02x", uuid[i]);
376 	printf("-");
377 	for (i = 8; i < 10; ++i)
378 		printf("%02x", uuid[i]);
379 	printf("-");
380 	for (i = 10; i < 16; ++i)
381 		printf("%02x", uuid[i]);
382 }
383 
384 // Refer to pg 1735 of Bluetooth Core Spec 4.0
385 static void _dump_scan_rsp_data(const uint8_t *buf, int len) {
386 	int pos = 0;
387 	int sublen, i;
388 	uint8_t type;
389 	uint16_t val;
390 	char *cval;
391 
392 	while (pos < len) {
393 		sublen = buf[pos];
394 		++pos;
395 		if (pos + sublen > len) {
396 			printf("Error: attempt to read past end of buffer (%d + %d > %d)\n", pos, sublen, len);
397 			return;
398 		}
399 		if (sublen == 0) {
400 			printf("Early return due to 0 length\n");
401 			return;
402 		}
403 		type = buf[pos];
404 		printf("        Type %02x", type);
405 		switch (type) {
406 			case 0x01:
407 				printf(" (Flags)\n");
408 				printf("           ");
409 				for (i = 0; i < 8; ++i)
410 					printf("%d", buf[pos+1] & (1 << (7-i)) ? 1 : 0);
411 				printf("\n");
412 				break;
413 			case 0x06:
414 				printf(" (128-bit Service UUIDs, more available)\n");
415 				goto print128;
416 			case 0x07:
417 				printf(" (128-bit Service UUIDs)\n");
418 print128:
419 				if ((sublen - 1) % 16 == 0) {
420 					uint8_t uuid[16];
421 					for (i = 0; i < sublen - 1; ++i) {
422 						uuid[15 - (i % 16)] = buf[pos+1+i];
423 						if ((i & 15) == 15) {
424 							printf("           ");
425 							_dump_uuid(uuid);
426 							printf("\n");
427 						}
428 					}
429 				}
430 				else {
431 					printf("Wrong length (%d, must be divisible by 16)\n", sublen-1);
432 				}
433 				break;
434 			case 0x09:
435 				printf(" (Complete Local Name)\n");
436 				printf("           ");
437 				for (i = 1; i < sublen; ++i)
438 					printf("%c", isprint(buf[pos+i]) ? buf[pos+i] : '.');
439 				printf("\n");
440 				break;
441 			case 0x0a:
442 				printf(" (Tx Power Level)\n");
443 				printf("           ");
444 				if (sublen-1 == 1) {
445 					cval = (char *)&buf[pos+1];
446 					printf("%d dBm\n", *cval);
447 				} else {
448 					printf("Wrong length (%d, should be 1)\n", sublen-1);
449 				}
450 				break;
451 			case 0x12:
452 				printf(" (Slave Connection Interval Range)\n");
453 				printf("           ");
454 				if (sublen-1 == 4) {
455 					val = (buf[pos+2] << 8) | buf[pos+1];
456 					printf("(%0.2f, ", val * 1.25);
457 					val = (buf[pos+4] << 8) | buf[pos+3];
458 					printf("%0.2f) ms\n", val * 1.25);
459 				}
460 				else {
461 					printf("Wrong length (%d, should be 4)\n", sublen-1);
462 				}
463 				break;
464 			case 0x16:
465 				printf(" (Service Data)\n");
466 				printf("           ");
467 				if (sublen-1 >= 2) {
468 					val = (buf[pos+2] << 8) | buf[pos+1];
469 					printf("UUID: %02x", val);
470 					if (sublen-1 > 2) {
471 						printf(", Additional:");
472 						for (i = 3; i < sublen; ++i)
473 							printf(" %02x", buf[pos+i]);
474 					}
475 					printf("\n");
476 				}
477 				else {
478 					printf("Wrong length (%d, should be >= 2)\n", sublen-1);
479 				}
480 				break;
481 			default:
482 				printf("\n");
483 				printf("           ");
484 				for (i = 1; i < sublen; ++i)
485 					printf(" %02x", buf[pos+i]);
486 				printf("\n");
487 		}
488 		pos += sublen;
489 	}
490 }
491 
492 void lell_print(const lell_packet *pkt)
493 {
494 	int i, opcode;
495 	if (lell_packet_is_data(pkt)) {
496 		int llid = pkt->symbols[4] & 0x3;
497 		static const char *llid_str[] = {
498 			"Reserved",
499 			"LL Data PDU / empty or L2CAP continuation",
500 			"LL Data PDU / L2CAP start",
501 			"LL Control PDU",
502 		};
503 
504 		printf("Data / AA %08x (%s) / %2d bytes\n", pkt->access_address,
505 		       pkt->flags.as_bits.access_address_ok ? "valid" : "invalid",
506 		       pkt->length);
507 		printf("    Channel Index: %d\n", pkt->channel_idx);
508 		printf("    LLID: %d / %s\n", llid, llid_str[llid]);
509 		printf("    NESN: %d  SN: %d  MD: %d\n", (pkt->symbols[4] >> 2) & 1,
510 												 (pkt->symbols[4] >> 3) & 1,
511 												 (pkt->symbols[4] >> 4) & 1);
512 		switch (llid) {
513 		case 3: // LL Control PDU
514 			opcode = pkt->symbols[6];
515 			static const char *opcode_str[] = {
516 				"LL_CONNECTION_UPDATE_REQ",
517 				"LL_CHANNEL_MAP_REQ",
518 				"LL_TERMINATE_IND",
519 				"LL_ENC_REQ",
520 				"LL_ENC_RSP",
521 				"LL_START_ENC_REQ",
522 				"LL_START_ENC_RSP",
523 				"LL_UNKNOWN_RSP",
524 				"LL_FEATURE_REQ",
525 				"LL_FEATURE_RSP",
526 				"LL_PAUSE_ENC_REQ",
527 				"LL_PAUSE_ENC_RSP",
528 				"LL_VERSION_IND",
529 				"LL_REJECT_IND",
530 				"LL_SLAVE_FEATURE_REQ",
531 				"LL_CONNECTION_PARAM_REQ",
532 				"LL_CONNECTION_PARAM_RSP",
533 				"LL_REJECT_IND_EXT",
534 				"LL_PING_REQ",
535 				"LL_PING_RSP",
536 				"Reserved for Future Use",
537 			};
538 			printf("    Opcode: %d / %s\n", opcode, opcode_str[(opcode<0x14)?opcode:0x14]);
539 			break;
540 		default:
541 			break;
542 		}
543 	} else {
544 		printf("Advertising / AA %08x (%s)/ %2d bytes\n", pkt->access_address,
545 		       pkt->flags.as_bits.access_address_ok ? "valid" : "invalid",
546 		       pkt->length);
547 		printf("    Channel Index: %d\n", pkt->channel_idx);
548 		printf("    Type:  %s\n", lell_get_adv_type_str(pkt));
549 
550 		switch(pkt->adv_type) {
551 			case ADV_IND:
552 				_dump_addr("AdvA:  ", pkt->symbols, 6, pkt->adv_tx_add);
553 				if (pkt->length-6 > 0) {
554 					printf("    AdvData:");
555 					for (i = 0; i < pkt->length - 6; ++i)
556 						printf(" %02x", pkt->symbols[12+i]);
557 					printf("\n");
558 					_dump_scan_rsp_data(&pkt->symbols[12], pkt->length-6);
559 				}
560 				break;
561 			case SCAN_REQ:
562 				_dump_addr("ScanA: ", pkt->symbols, 6, pkt->adv_tx_add);
563 				_dump_addr("AdvA:  ", pkt->symbols, 12, pkt->adv_rx_add);
564 				break;
565 			case SCAN_RSP:
566 				_dump_addr("AdvA:  ", pkt->symbols, 6, pkt->adv_tx_add);
567 				printf("    ScanRspData:");
568 				for (i = 0; i < pkt->length - 6; ++i)
569 					printf(" %02x", pkt->symbols[12+i]);
570 				printf("\n");
571 				_dump_scan_rsp_data(&pkt->symbols[12], pkt->length-6);
572 				break;
573 			case CONNECT_REQ:
574 				_dump_addr("InitA: ", pkt->symbols, 6, pkt->adv_tx_add);
575 				_dump_addr("AdvA:  ", pkt->symbols, 12, pkt->adv_rx_add);
576 				_dump_32("AA:    ", pkt->symbols, 18);
577 				_dump_24("CRCInit: ", pkt->symbols, 22);
578 				_dump_8("WinSize: ", pkt->symbols, 25);
579 				_dump_16("WinOffset: ", pkt->symbols, 26);
580 				_dump_16("Interval: ", pkt->symbols, 28);
581 				_dump_16("Latency: ", pkt->symbols, 30);
582 				_dump_16("Timeout: ", pkt->symbols, 32);
583 
584 				printf("    ChM:");
585 				for (i = 0; i < 5; ++i)
586 					printf(" %02x", pkt->symbols[34+i]);
587 				printf("\n");
588 
589 				printf("    Hop: %d\n", pkt->symbols[39] & 0x1f);
590 				printf("    SCA: %d, %s\n",
591 						pkt->symbols[39] >> 5,
592 						CONNECT_SCA[pkt->symbols[39] >> 5]);
593 				break;
594 		}
595 	}
596 
597 	printf("\n");
598 	printf("    Data: ");
599 	for (i = 6; i < 6 + pkt->length; ++i)
600 		printf(" %02x", pkt->symbols[i]);
601 	printf("\n");
602 
603 	printf("    CRC:  ");
604 	for (i = 0; i < 3; ++i)
605 		printf(" %02x", pkt->symbols[6 + pkt->length + i]);
606 	printf("\n");
607 }
608