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