1 /* -*- c -*- */ 2 /* 3 * Copyright 2007 - 2013 Dominic Spill, Michael Ossmann, Will Code 4 * 5 * This file is part of libbtbb 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with libbtbb; see the file COPYING. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 #include "bluetooth_packet.h" 24 #include "bluetooth_piconet.h" 25 #include "uthash.h" 26 #include <stdlib.h> 27 #include <stdio.h> 28 29 int perm_table_initialized = 0; 30 char perm_table[0x20][0x20][0x200]; 31 32 btbb_piconet * 33 btbb_piconet_new(void) 34 { 35 btbb_piconet *pn = (btbb_piconet *)calloc(1, sizeof(btbb_piconet)); 36 pn->refcount = 1; 37 return pn; 38 } 39 40 void 41 btbb_piconet_ref(btbb_piconet *pn) 42 { 43 pn->refcount++; 44 } 45 46 void 47 btbb_piconet_unref(btbb_piconet *pn) 48 { 49 pn->refcount--; 50 if (pn->refcount == 0) 51 free(pn); 52 } 53 54 void btbb_init_piconet(btbb_piconet *pn, uint32_t lap) 55 { 56 pn->LAP = lap; 57 btbb_piconet_set_flag(pn, BTBB_LAP_VALID, 1); 58 } 59 60 void btbb_piconet_set_flag(btbb_piconet *pn, int flag, int val) 61 { 62 uint32_t mask = 1L << flag; 63 pn->flags &= ~mask; 64 if (val) 65 pn->flags |= mask; 66 } 67 68 int btbb_piconet_get_flag(const btbb_piconet *pn, const int flag) 69 { 70 uint32_t mask = 1L << flag; 71 return ((pn->flags & mask) != 0); 72 } 73 74 void btbb_piconet_set_uap(btbb_piconet *pn, uint8_t uap) 75 { 76 pn->UAP = uap; 77 btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); 78 } 79 80 uint8_t btbb_piconet_get_uap(const btbb_piconet *pn) 81 { 82 return pn->UAP; 83 } 84 85 uint32_t btbb_piconet_get_lap(const btbb_piconet *pn) 86 { 87 return pn->LAP; 88 } 89 90 uint16_t btbb_piconet_get_nap(const btbb_piconet *pn) 91 { 92 return pn->NAP; 93 } 94 95 uint64_t btbb_piconet_get_bdaddr(const btbb_piconet *pn) 96 { 97 return ((uint64_t) pn->NAP) << 32 | pn->UAP << 24 | pn->LAP; 98 } 99 100 int btbb_piconet_get_clk_offset(const btbb_piconet *pn) 101 { 102 return pn->clk_offset; 103 } 104 105 void btbb_piconet_set_clk_offset(btbb_piconet *pn, int clk_offset) 106 { 107 pn->clk_offset = clk_offset; 108 } 109 110 void btbb_piconet_set_afh_map(btbb_piconet *pn, uint8_t *afh_map) { 111 int i; 112 // DGS: Unroll this? 113 for(i=0; i<10; i++) 114 pn->afh_map[i] = afh_map[i]; 115 } 116 117 uint8_t *btbb_piconet_get_afh_map(btbb_piconet *pn) { 118 return pn->afh_map; 119 } 120 121 void btbb_piconet_set_channel_seen(btbb_piconet *pn, uint8_t channel) 122 { 123 pn->afh_map[channel/8] |= 0x1 << (channel % 8); 124 } 125 126 /* do all the precalculation that can be done before knowing the address */ 127 void precalc(btbb_piconet *pn) 128 { 129 int i; 130 131 /* populate frequency register bank*/ 132 for (i = 0; i < BT_NUM_CHANNELS; i++) 133 pn->bank[i] = ((i * 2) % BT_NUM_CHANNELS); 134 /* actual frequency is 2402 + pn->bank[i] MHz */ 135 136 } 137 138 /* do precalculation that requires the address */ 139 void address_precalc(int address, btbb_piconet *pn) 140 { 141 /* precalculate some of single_hop()/gen_hop()'s variables */ 142 pn->a1 = (address >> 23) & 0x1f; 143 pn->b = (address >> 19) & 0x0f; 144 pn->c1 = ((address >> 4) & 0x10) + 145 ((address >> 3) & 0x08) + 146 ((address >> 2) & 0x04) + 147 ((address >> 1) & 0x02) + 148 (address & 0x01); 149 pn->d1 = (address >> 10) & 0x1ff; 150 pn->e = ((address >> 7) & 0x40) + 151 ((address >> 6) & 0x20) + 152 ((address >> 5) & 0x10) + 153 ((address >> 4) & 0x08) + 154 ((address >> 3) & 0x04) + 155 ((address >> 2) & 0x02) + 156 ((address >> 1) & 0x01); 157 } 158 159 #ifdef WC4 160 /* These are optimization experiments, which don't help much for 161 * x86. Hold on to them to see whether they're useful on ARM. */ 162 163 #ifdef NEVER 164 #define BUTTERFLY(z,p,c,a,b) \ 165 if ( ((p&(1<<c))!=0) & (((z&(1<<a))!=0) ^ ((z&(1<<b))!=0)) ) \ 166 z ^= ((1<<a)|(1<<b)) 167 #endif 168 169 #define BUTTERFLY(z,p,c,a,b) \ 170 if ( (((z>>a)^(z>>b)) & (p>>c)) & 0x1 ) \ 171 z ^= ((1<<a)|(1<<b)) 172 173 int perm5(int z, int p_high, int p_low) 174 { 175 int p = (p_high << 5) | p_low; 176 BUTTERFLY(z,p,13,1,2); 177 BUTTERFLY(z,p,12,0,3); 178 BUTTERFLY(z,p,11,1,3); 179 BUTTERFLY(z,p,10,2,4); 180 BUTTERFLY(z,p, 9,0,3); 181 BUTTERFLY(z,p, 8,1,4); 182 BUTTERFLY(z,p, 7,3,4); 183 BUTTERFLY(z,p, 6,0,2); 184 BUTTERFLY(z,p, 5,1,3); 185 BUTTERFLY(z,p, 4,0,4); 186 BUTTERFLY(z,p, 3,3,4); 187 BUTTERFLY(z,p, 2,1,2); 188 BUTTERFLY(z,p, 1,2,3); 189 BUTTERFLY(z,p, 0,0,1); 190 191 return z; 192 } 193 #endif // WC4 194 195 /* 5 bit permutation */ 196 /* assumes z is constrained to 5 bits, p_high to 5 bits, p_low to 9 bits */ 197 int perm5(int z, int p_high, int p_low) 198 { 199 int i, tmp, output, z_bit[5], p[14]; 200 int index1[] = {0, 2, 1, 3, 0, 1, 0, 3, 1, 0, 2, 1, 0, 1}; 201 int index2[] = {1, 3, 2, 4, 4, 3, 2, 4, 4, 3, 4, 3, 3, 2}; 202 203 /* bits of p_low and p_high are control signals */ 204 for (i = 0; i < 9; i++) 205 p[i] = (p_low >> i) & 0x01; 206 for (i = 0; i < 5; i++) 207 p[i+9] = (p_high >> i) & 0x01; 208 209 /* bit swapping will be easier with an array of bits */ 210 for (i = 0; i < 5; i++) 211 z_bit[i] = (z >> i) & 0x01; 212 213 /* butterfly operations */ 214 for (i = 13; i >= 0; i--) { 215 /* swap bits according to index arrays if control signal tells us to */ 216 if (p[i]) { 217 tmp = z_bit[index1[i]]; 218 z_bit[index1[i]] = z_bit[index2[i]]; 219 z_bit[index2[i]] = tmp; 220 } 221 } 222 223 /* reconstruct output from rearranged bits */ 224 output = 0; 225 for (i = 0; i < 5; i++) 226 output += z_bit[i] << i; 227 228 return(output); 229 } 230 231 void perm_table_init(void) 232 { 233 /* populate perm_table for all possible inputs */ 234 int z, p_high, p_low; 235 for (z = 0; z < 0x20; z++) 236 for (p_high = 0; p_high < 0x20; p_high++) 237 for (p_low = 0; p_low < 0x200; p_low++) 238 perm_table[z][p_high][p_low] = perm5(z, p_high, p_low); 239 } 240 241 /* drop-in replacement for perm5() using lookup table */ 242 int fast_perm(int z, int p_high, int p_low) 243 { 244 if (!perm_table_initialized) { 245 perm_table_init(); 246 perm_table_initialized = 1; 247 } 248 249 return(perm_table[z][p_high][p_low]); 250 } 251 252 /* generate the complete hopping sequence */ 253 static void gen_hops(btbb_piconet *pn) 254 { 255 /* a, b, c, d, e, f, x, y1, y2 are variable names used in section 2.6 of the spec */ 256 /* b is already defined */ 257 /* e is already defined */ 258 int a, c, d, f, x; 259 int h, i, j, k, c_flipped, perm_in, perm_out; 260 261 /* sequence index = clock >> 1 */ 262 /* (hops only happen at every other clock value) */ 263 int index = 0; 264 f = 0; 265 266 /* nested loops for optimization (not recalculating every variable with every clock tick) */ 267 for (h = 0; h < 0x04; h++) { /* clock bits 26-27 */ 268 for (i = 0; i < 0x20; i++) { /* clock bits 21-25 */ 269 a = pn->a1 ^ i; 270 for (j = 0; j < 0x20; j++) { /* clock bits 16-20 */ 271 c = pn->c1 ^ j; 272 c_flipped = c ^ 0x1f; 273 for (k = 0; k < 0x200; k++) { /* clock bits 7-15 */ 274 d = pn->d1 ^ k; 275 for (x = 0; x < 0x20; x++) { /* clock bits 2-6 */ 276 perm_in = ((x + a) % 32) ^ pn->b; 277 /* y1 (clock bit 1) = 0, y2 = 0 */ 278 perm_out = fast_perm(perm_in, c, d); 279 pn->sequence[index] = pn->bank[(perm_out + pn->e + f) % BT_NUM_CHANNELS]; 280 if (btbb_piconet_get_flag(pn, BTBB_IS_AFH)) { 281 pn->sequence[index + 1] = pn->sequence[index]; 282 } else { 283 /* y1 (clock bit 1) = 1, y2 = 32 */ 284 perm_out = fast_perm(perm_in, c_flipped, d); 285 pn->sequence[index + 1] = pn->bank[(perm_out + pn->e + f + 32) % BT_NUM_CHANNELS]; 286 } 287 index += 2; 288 } 289 f += 16; 290 } 291 } 292 } 293 } 294 } 295 296 /* Function to calculate piconet hopping patterns and add to hash map */ 297 void gen_hop_pattern(btbb_piconet *pn) 298 { 299 printf("\nCalculating complete hopping sequence.\n"); 300 /* this holds the entire hopping sequence */ 301 pn->sequence = (char*) malloc(SEQUENCE_LENGTH); 302 303 precalc(pn); 304 address_precalc(((pn->UAP<<24) | pn->LAP) & 0xfffffff, pn); 305 gen_hops(pn); 306 307 printf("Hopping sequence calculated.\n"); 308 } 309 310 /* Container for hopping pattern */ 311 typedef struct { 312 uint64_t key; /* afh flag + address */ 313 char *sequence; 314 UT_hash_handle hh; 315 } hopping_struct; 316 317 static hopping_struct *hopping_map = NULL; 318 319 /* Function to fetch piconet hopping patterns */ 320 void get_hop_pattern(btbb_piconet *pn) 321 { 322 hopping_struct *s; 323 uint64_t key; 324 325 /* Two stages to avoid "left shift count >= width of type" warning */ 326 key = btbb_piconet_get_flag(pn, BTBB_IS_AFH); 327 key = (key<<32) | (pn->UAP<<24) | pn->LAP; 328 HASH_FIND(hh, hopping_map, &key, 4, s); 329 330 if (s == NULL) { 331 gen_hop_pattern(pn); 332 s = malloc(sizeof(hopping_struct)); 333 s->key = key; 334 s->sequence = pn->sequence; 335 HASH_ADD(hh, hopping_map, key, 4, s); 336 } else { 337 printf("\nFound hopping sequence in cache.\n"); 338 pn->sequence = s->sequence; 339 } 340 } 341 342 /* determine channel for a particular hop */ 343 /* replaced with gen_hops() for a complete sequence but could still come in handy */ 344 char single_hop(int clock, btbb_piconet *pn) 345 { 346 int a, c, d, f, x, y1, y2; 347 348 /* following variable names used in section 2.6 of the spec */ 349 x = (clock >> 2) & 0x1f; 350 y1 = (clock >> 1) & 0x01; 351 y2 = y1 << 5; 352 a = (pn->a1 ^ (clock >> 21)) & 0x1f; 353 /* b is already defined */ 354 c = (pn->c1 ^ (clock >> 16)) & 0x1f; 355 d = (pn->d1 ^ (clock >> 7)) & 0x1ff; 356 /* e is already defined */ 357 f = (clock >> 3) & 0x1fffff0; 358 359 /* hop selection */ 360 return(pn->bank[(fast_perm(((x + a) % 32) ^ pn->b, (y1 * 0x1f) ^ c, d) + pn->e + f + y2) % BT_NUM_CHANNELS]); 361 } 362 363 /* look up channel for a particular hop */ 364 char hop(int clock, btbb_piconet *pn) 365 { 366 return pn->sequence[clock]; 367 } 368 369 static char aliased_channel(char channel) 370 { 371 return ((channel + 24) % ALIASED_CHANNELS) + 26; 372 } 373 374 /* create list of initial candidate clock values (hops with same channel as first observed hop) */ 375 static int init_candidates(char channel, int known_clock_bits, btbb_piconet *pn) 376 { 377 int i; 378 int count = 0; /* total number of candidates */ 379 char observable_channel; /* accounts for aliasing if necessary */ 380 381 /* only try clock values that match our known bits */ 382 for (i = known_clock_bits; i < SEQUENCE_LENGTH; i += 0x40) { 383 if (pn->aliased) 384 observable_channel = aliased_channel(pn->sequence[i]); 385 else 386 observable_channel = pn->sequence[i]; 387 if (observable_channel == channel) 388 pn->clock_candidates[count++] = i; 389 //FIXME ought to throw exception if count gets too big 390 } 391 return count; 392 } 393 394 /* initialize the hop reversal process */ 395 int btbb_init_hop_reversal(int aliased, btbb_piconet *pn) 396 { 397 int max_candidates; 398 uint32_t clock; 399 400 get_hop_pattern(pn); 401 402 if(aliased) 403 max_candidates = (SEQUENCE_LENGTH / ALIASED_CHANNELS) / 32; 404 else 405 max_candidates = (SEQUENCE_LENGTH / BT_NUM_CHANNELS) / 32; 406 /* this can hold twice the approximate number of initial candidates */ 407 pn->clock_candidates = (uint32_t*) malloc(sizeof(uint32_t) * max_candidates); 408 409 clock = (pn->clk_offset + pn->first_pkt_time) & 0x3f; 410 pn->num_candidates = init_candidates(pn->pattern_channels[0], clock, pn); 411 pn->winnowed = 0; 412 btbb_piconet_set_flag(pn, BTBB_HOP_REVERSAL_INIT, 1); 413 btbb_piconet_set_flag(pn, BTBB_CLK27_VALID, 0); 414 btbb_piconet_set_flag(pn, BTBB_IS_ALIASED, aliased); 415 416 printf("%d initial CLK1-27 candidates\n", pn->num_candidates); 417 418 return pn->num_candidates; 419 } 420 421 void try_hop(btbb_packet *pkt, btbb_piconet *pn) 422 { 423 uint8_t filter_uap = pn->UAP; 424 425 /* Decode packet - fixing clock drift in the process */ 426 btbb_decode(pkt, pn); 427 428 if (btbb_piconet_get_flag(pn, BTBB_HOP_REVERSAL_INIT)) { 429 //pn->winnowed = 0; 430 pn->pattern_indices[pn->packets_observed] = 431 pkt->clkn - pn->first_pkt_time; 432 pn->pattern_channels[pn->packets_observed] = pkt->channel; 433 pn->packets_observed++; 434 pn->total_packets_observed++; 435 btbb_winnow(pn); 436 if (btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { 437 printf("got CLK1-27\n"); 438 printf("clock offset = %d.\n", pn->clk_offset); 439 } 440 } else { 441 if (btbb_piconet_get_flag(pn, BTBB_CLK6_VALID)) { 442 btbb_uap_from_header(pkt, pn); 443 if (btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { 444 printf("got CLK1-27\n"); 445 printf("clock offset = %d.\n", pn->clk_offset); 446 } 447 } else { 448 if (btbb_uap_from_header(pkt, pn)) { 449 if (filter_uap == pn->UAP) { 450 printf("got CLK1-6\n"); 451 btbb_init_hop_reversal(0, pn); 452 btbb_winnow(pn); 453 } else { 454 printf("failed to confirm UAP\n"); 455 } 456 } 457 } 458 } 459 460 if(!btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) { 461 btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); 462 pn->UAP = filter_uap; 463 } 464 } 465 466 /* return the observable channel (26-50) for a given channel (0-78) */ 467 /* reset UAP/clock discovery */ 468 static void reset(btbb_piconet *pn) 469 { 470 //printf("no candidates remaining! starting over . . .\n"); 471 472 if(btbb_piconet_get_flag(pn, BTBB_HOP_REVERSAL_INIT)) { 473 free(pn->clock_candidates); 474 pn->sequence = NULL; 475 } 476 btbb_piconet_set_flag(pn, BTBB_GOT_FIRST_PACKET, 0); 477 btbb_piconet_set_flag(pn, BTBB_HOP_REVERSAL_INIT, 0); 478 btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 0); 479 btbb_piconet_set_flag(pn, BTBB_CLK6_VALID, 0); 480 btbb_piconet_set_flag(pn, BTBB_CLK27_VALID, 0); 481 pn->packets_observed = 0; 482 483 /* 484 * If we have recently observed two packets in a row on the same 485 * channel, try AFH next time. If not, don't. 486 */ 487 btbb_piconet_set_flag(pn, BTBB_IS_AFH, 488 btbb_piconet_get_flag(pn, BTBB_LOOKS_LIKE_AFH)); 489 btbb_piconet_set_flag(pn, BTBB_LOOKS_LIKE_AFH, 0); 490 //int i; 491 //for(i=0; i<10; i++) 492 // pn->afh_map[i] = 0; 493 } 494 495 /* narrow a list of candidate clock values based on a single observed hop */ 496 static int channel_winnow(int offset, char channel, btbb_piconet *pn) 497 { 498 int i; 499 int new_count = 0; /* number of candidates after winnowing */ 500 char observable_channel; /* accounts for aliasing if necessary */ 501 502 /* check every candidate */ 503 for (i = 0; i < pn->num_candidates; i++) { 504 if (pn->aliased) 505 observable_channel = aliased_channel(pn->sequence[(pn->clock_candidates[i] + offset) % SEQUENCE_LENGTH]); 506 else 507 observable_channel = pn->sequence[(pn->clock_candidates[i] + offset) % SEQUENCE_LENGTH]; 508 if (observable_channel == channel) { 509 /* this candidate matches the latest hop */ 510 /* blow away old list of candidates with new one */ 511 /* safe because new_count can never be greater than i */ 512 pn->clock_candidates[new_count++] = pn->clock_candidates[i]; 513 } 514 } 515 pn->num_candidates = new_count; 516 517 if (new_count == 1) { 518 // Calculate clock offset for CLKN, not CLK1-27 519 pn->clk_offset = ((pn->clock_candidates[0]<<1) - (pn->first_pkt_time<<1)); 520 printf("\nAcquired CLK1-27 = 0x%07x\n", pn->clock_candidates[0]); 521 btbb_piconet_set_flag(pn, BTBB_CLK27_VALID, 1); 522 } 523 else if (new_count == 0) { 524 reset(pn); 525 } 526 //else { 527 //printf("%d CLK1-27 candidates remaining (channel=%d)\n", new_count, channel); 528 //} 529 530 return new_count; 531 } 532 533 /* narrow a list of candidate clock values based on all observed hops */ 534 int btbb_winnow(btbb_piconet *pn) 535 { 536 int new_count = pn->num_candidates; 537 int index, last_index; 538 uint8_t channel, last_channel; 539 540 for (; pn->winnowed < pn->packets_observed; pn->winnowed++) { 541 index = pn->pattern_indices[pn->winnowed]; 542 channel = pn->pattern_channels[pn->winnowed]; 543 new_count = channel_winnow(index, channel, pn); 544 if (new_count <= 1) 545 break; 546 547 if (pn->packets_observed > 0) { 548 last_index = pn->pattern_indices[pn->winnowed - 1]; 549 last_channel = pn->pattern_channels[pn->winnowed - 1]; 550 /* 551 * Two packets in a row on the same channel should only 552 * happen if adaptive frequency hopping is in use. 553 * There can be false positives, though, especially if 554 * there is aliasing. 555 */ 556 if (!btbb_piconet_get_flag(pn, BTBB_LOOKS_LIKE_AFH) 557 && (index == last_index + 1) 558 && (channel == last_channel)) { 559 btbb_piconet_set_flag(pn, BTBB_LOOKS_LIKE_AFH, 1); 560 printf("Hopping pattern appears to be AFH\n"); 561 } 562 } 563 } 564 565 return new_count; 566 } 567 568 /* use packet headers to determine UAP */ 569 int btbb_uap_from_header(btbb_packet *pkt, btbb_piconet *pn) 570 { 571 uint8_t UAP; 572 int count, crc_chk, first_clock = 0; 573 574 int starting = 0; 575 int remaining = 0; 576 uint32_t clkn = pkt->clkn; 577 578 if (!btbb_piconet_get_flag(pn, BTBB_GOT_FIRST_PACKET)) 579 pn->first_pkt_time = clkn; 580 581 // Set afh channel map 582 pn->afh_map[pkt->channel/8] |= 0x1 << (pkt->channel % 8); 583 584 if (pn->packets_observed < MAX_PATTERN_LENGTH) { 585 pn->pattern_indices[pn->packets_observed] = clkn - pn->first_pkt_time; 586 pn->pattern_channels[pn->packets_observed] = pkt->channel; 587 } else { 588 printf("Oops. More hops than we can remember.\n"); 589 reset(pn); 590 return 0; //FIXME ought to throw exception 591 } 592 pn->packets_observed++; 593 pn->total_packets_observed++; 594 595 /* try every possible first packet clock value */ 596 for (count = 0; count < 64; count++) { 597 /* skip eliminated candidates unless this is our first time through */ 598 if (pn->clock6_candidates[count] > -1 599 || !btbb_piconet_get_flag(pn, BTBB_GOT_FIRST_PACKET)) { 600 /* clock value for the current packet assuming count was the clock of the first packet */ 601 int clock = (count + clkn - pn->first_pkt_time) % 64; 602 starting++; 603 UAP = try_clock(clock, pkt); 604 crc_chk = -1; 605 606 /* if this is the first packet: populate the candidate list */ 607 /* if not: check CRCs if UAPs match */ 608 if (!btbb_piconet_get_flag(pn, BTBB_GOT_FIRST_PACKET) 609 || UAP == pn->clock6_candidates[count]) 610 crc_chk = crc_check(clock, pkt); 611 612 if (btbb_piconet_get_flag(pn, BTBB_UAP_VALID) && 613 (UAP != pn->UAP)) 614 crc_chk = -1; 615 616 switch(crc_chk) { 617 case -1: /* UAP mismatch */ 618 case 0: /* CRC failure */ 619 pn->clock6_candidates[count] = -1; 620 break; 621 622 case 1: /* inconclusive result */ 623 case 2: /* Inconclusive, but looks better */ 624 pn->clock6_candidates[count] = UAP; 625 /* remember this count because it may be the correct clock of the first packet */ 626 first_clock = count; 627 remaining++; 628 break; 629 630 default: /* CRC success */ 631 pn->clk_offset = (count - (pn->first_pkt_time & 0x3f)) & 0x3f; 632 if (!btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) 633 printf("Correct CRC! UAP = 0x%x found after %d total packets.\n", 634 UAP, pn->total_packets_observed); 635 else 636 printf("Correct CRC! CLK6 = 0x%x found after %d total packets.\n", 637 pn->clk_offset, pn->total_packets_observed); 638 pn->UAP = UAP; 639 btbb_piconet_set_flag(pn, BTBB_CLK6_VALID, 1); 640 btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); 641 pn->total_packets_observed = 0; 642 return 1; 643 } 644 } 645 } 646 647 btbb_piconet_set_flag(pn, BTBB_GOT_FIRST_PACKET, 1); 648 649 //printf("reduced from %d to %d CLK1-6 candidates\n", starting, remaining); 650 651 if (remaining == 1) { 652 pn->clk_offset = (first_clock - (pn->first_pkt_time & 0x3f)) & 0x3f; 653 if (!btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) 654 printf("We have a winner! UAP = 0x%x found after %d total packets.\n", 655 pn->clock6_candidates[first_clock], pn->total_packets_observed); 656 else 657 printf("We have a winner! CLK6 = 0x%x found after %d total packets.\n", 658 pn->clk_offset, pn->total_packets_observed); 659 pn->UAP = pn->clock6_candidates[first_clock]; 660 btbb_piconet_set_flag(pn, BTBB_CLK6_VALID, 1); 661 btbb_piconet_set_flag(pn, BTBB_UAP_VALID, 1); 662 pn->total_packets_observed = 0; 663 return 1; 664 } 665 666 if (remaining == 0) { 667 reset(pn); 668 } 669 670 return 0; 671 } 672 673 /* add a packet to the queue */ 674 static void enqueue(btbb_packet *pkt, btbb_piconet *pn) 675 { 676 pkt_queue *head; 677 //pkt_queue item; 678 679 btbb_packet_ref(pkt); 680 pkt_queue item = {pkt, NULL}; 681 head = pn->queue; 682 683 if (head == NULL) { 684 pn->queue = &item; 685 } else { 686 for(; head->next != NULL; head = head->next) 687 ; 688 head->next = &item; 689 } 690 } 691 692 /* pull the first packet from the queue (FIFO) */ 693 static btbb_packet *dequeue(btbb_piconet *pn) 694 { 695 btbb_packet *pkt; 696 697 if (pn->queue == NULL) { 698 pkt = NULL; 699 } else { 700 pkt = pn->queue->pkt; 701 pn->queue = pn->queue->next; 702 btbb_packet_unref(pkt); 703 } 704 705 return pkt; 706 } 707 708 /* decode the whole packet */ 709 int btbb_decode(btbb_packet* pkt, btbb_piconet *pn) 710 { 711 btbb_packet_set_flag(pkt, BTBB_HAS_PAYLOAD, 0); 712 uint8_t clk6, i, best_clk; 713 int rv = 0, max_rv = 0; 714 if (btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { 715 /* Removing this section until we can more reliably handle AFH */ 716 //if(pn->sequence == NULL) 717 // get_hop_pattern(pn); 718 //clk6 = pkt->clock & 0x3f; 719 //for(i=0; i<64; i++) { 720 // pkt->clock = (pkt->clock & 0xffffffc0) | ((clk6 + i) & 0x3f); 721 // if ((pn->sequence[pkt->clock] == pkt->channel) && (btbb_decode_header(pkt))) { 722 // rv = btbb_decode_payload(pkt); 723 // if(rv > max_rv) { 724 // max_rv = rv; 725 // best_clk = (clk6 + i) & 0x3f; 726 // } 727 // } 728 //} 729 730 // If we found nothing, try again, ignoring channel 731 if(max_rv <= 1) { 732 clk6 = pkt->clock & 0x3f; 733 for(i=0; i<64; i++) { 734 pkt->clock = (pkt->clock & 0xffffffc0) | ((clk6 + i) & 0x3f); 735 if (btbb_decode_header(pkt)) { 736 rv = btbb_decode_payload(pkt); 737 if(rv > max_rv) { 738 //printf("Packet decoded with clock 0x%07x (rv=%d)\n", pkt->clock, rv); 739 //btbb_print_packet(pkt); 740 max_rv = rv; 741 best_clk = (clk6 + i) & 0x3f; 742 } 743 } 744 } 745 } 746 } else 747 if (btbb_decode_header(pkt)) { 748 for(i=0; i<64; i++) { 749 pkt->clock = (pkt->clock & 0xffffffc0) | (i & 0x3f); 750 if (btbb_decode_header(pkt)) { 751 rv = btbb_decode_payload(pkt); 752 if(rv > max_rv) { 753 //printf("Packet decoded with clock 0x%02x (rv=%d)\n", i, rv); 754 //btbb_print_packet(pkt); 755 max_rv = rv; 756 best_clk = i & 0x3f; 757 } 758 } 759 } 760 } 761 /* If we were successful, print the packet */ 762 if(max_rv > 0) { 763 pkt->clock = (pkt->clock & 0xffffffc0) | (best_clk & 0x3f); 764 btbb_decode_payload(pkt); 765 printf("Packet decoded with clock 0x%02x (rv=%d)\n", i, rv); 766 btbb_print_packet(pkt); 767 } 768 769 return max_rv; 770 } 771 772 /* Print AFH map from observed packets */ 773 void btbb_print_afh_map(btbb_piconet *pn) { 774 uint8_t *afh_map; 775 afh_map = pn->afh_map; 776 777 /* Printed ch78 -> ch0 */ 778 printf("\tAFH Map=0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 779 afh_map[9], afh_map[8], afh_map[7], afh_map[6], afh_map[5], 780 afh_map[4], afh_map[3], afh_map[2], afh_map[1], afh_map[0]); 781 } 782 783 /* Container for survey piconets */ 784 typedef struct { 785 uint32_t key; /* LAP */ 786 btbb_piconet *pn; 787 UT_hash_handle hh; 788 } survey_hash; 789 790 static survey_hash *piconet_survey = NULL; 791 792 /* A bit of a hack? to set survey mode */ 793 static int survey_mode = 0; 794 int btbb_init_survey() { 795 survey_mode = 1; 796 return 0; 797 } 798 799 /* Check for existing piconets in survey results */ 800 btbb_piconet *get_piconet(uint32_t lap) 801 { 802 survey_hash *s; 803 btbb_piconet *pn; 804 HASH_FIND(hh, piconet_survey, &lap, 4, s); 805 806 if (s == NULL) { 807 pn = btbb_piconet_new(); 808 btbb_init_piconet(pn, lap); 809 810 s = malloc(sizeof(survey_hash)); 811 s->key = lap; 812 s->pn = pn; 813 HASH_ADD(hh, piconet_survey, key, 4, s); 814 } else { 815 pn = s->pn; 816 } 817 return pn; 818 } 819 820 /* Destructively iterate over survey results */ 821 btbb_piconet *btbb_next_survey_result() { 822 btbb_piconet *pn = NULL; 823 survey_hash *tmp; 824 825 if (piconet_survey != NULL) { 826 pn = piconet_survey->pn; 827 tmp = piconet_survey; 828 piconet_survey = piconet_survey->hh.next; 829 free(tmp); 830 } 831 return pn; 832 } 833 834 int btbb_process_packet(btbb_packet *pkt, btbb_piconet *pn) { 835 if (survey_mode) { 836 pn = get_piconet(btbb_packet_get_lap(pkt)); 837 btbb_piconet_set_channel_seen(pn, pkt->channel); 838 if(btbb_header_present(pkt) && !btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) 839 btbb_uap_from_header(pkt, pn); 840 return 0; 841 } 842 /* If piconet structure is given, a LAP is given, and packet 843 * header is readable, do further analysis. If UAP has not yet 844 * been determined, attempt to calculate it from headers. Once 845 * UAP is known, try to determine clk6 and clk27. Once clocks 846 * are known, follow the piconet. */ 847 if (pn && btbb_piconet_get_flag(pn, BTBB_LAP_VALID) && 848 btbb_header_present(pkt)) { 849 850 /* Have LAP/UAP/clocks, now hopping along with the piconet. */ 851 if (btbb_piconet_get_flag(pn, BTBB_FOLLOWING)) { 852 btbb_packet_set_uap(pkt, btbb_piconet_get_uap(pn)); 853 btbb_packet_set_flag(pkt, BTBB_CLK6_VALID, 1); 854 btbb_packet_set_flag(pkt, BTBB_CLK27_VALID, 1); 855 856 if(btbb_decode(pkt, pn)) 857 btbb_print_packet(pkt); 858 else 859 printf("Failed to decode packet\n"); 860 } 861 862 /* Have LAP/UAP, need clocks. */ 863 else if (btbb_piconet_get_uap(pn)) { 864 try_hop(pkt, pn); 865 if (btbb_piconet_get_flag(pn, BTBB_CLK6_VALID) && 866 btbb_piconet_get_flag(pn, BTBB_CLK27_VALID)) { 867 btbb_piconet_set_flag(pn, BTBB_FOLLOWING, 1); 868 return -1; 869 } 870 } 871 872 /* Have LAP, need UAP. */ 873 else { 874 btbb_uap_from_header(pkt, pn); 875 } 876 } 877 return 0; 878 } 879