xref: /libbtbb/lib/src/bluetooth_piconet.c (revision 7e0e8e624f1b87b68c4032d236e1cfa44bd122c9)
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