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