Beispiel #1
0
static void cb_dump_bitstream(void* args, usb_pkt_rx *rx, int bank)
{
	/* unused parameter */ args = args;

	unpack_symbols(rx->data, symbols[bank]);
	fprintf(stderr, "rx block timestamp %u * 100 nanoseconds\n", rx->clk100ns);
	if (dumpfile == NULL) {
		if (fwrite(symbols[bank], sizeof(u8), BANK_LEN, stdout) != 1) {;}
    } else {
		if (fwrite(symbols[bank], sizeof(u8), BANK_LEN, dumpfile) != 1) {;}
	}
}
Beispiel #2
0
static void cb_dump_bitstream(void* args, usb_pkt_rx *rx, int bank)
{
	int i;
	char nl = '\n';

	UNUSED(args);

	unpack_symbols(rx->data, br_symbols[bank]);

	// convert to ascii
	for (i = 0; i < BANK_LEN; ++i)
		br_symbols[bank][i] += 0x30;

	fprintf(stderr, "rx block timestamp %u * 100 nanoseconds\n", rx->clk100ns);
	if (dumpfile == NULL) {
		if (fwrite(br_symbols[bank], sizeof(u8), BANK_LEN, stdout) != 1) {;}
		fwrite(&nl, sizeof(u8), 1, stdout);
    } else {
		if (fwrite(br_symbols[bank], sizeof(u8), BANK_LEN, dumpfile) != 1) {;}
		fwrite(&nl, sizeof(u8), 1, dumpfile);
	}
}
Beispiel #3
0
/*
 * Sniff Bluetooth Low Energy packets.  So far this is just a proof of concept
 * that only captures advertising packets.
 */
static void cb_btle(void* args, usb_pkt_rx *rx, int bank)
{
	char syms[BANK_LEN * NUM_BANKS];
	int i, j, k;
	uint32_t access_address = 0;
	uint32_t clk100ns; /* in 100 nanosecond units */
	char *channel_rssi_history;
	int8_t signal_level;
	int8_t noise_level;
	int8_t snr;
	time_t systime;
	uint8_t byte;

	/* unused parameter */ args = args;

	/* Sanity check */
	if (rx->channel > (NUM_CHANNELS-1))
		return;

	clk100ns = letoh32(rx->clk100ns); /* wire format is le32 */
	unpack_symbols(rx->data, symbols[bank]);

	/* Shift rssi max history and append current max */
	channel_rssi_history = rssi_history[rx->channel];
	for(i = 1; i < RSSI_HISTORY_LEN; i++) {
		int8_t v = channel_rssi_history[i];
		channel_rssi_history[i - 1] = v;
	}
	channel_rssi_history[RSSI_HISTORY_LEN-1] = rx->rssi_max;

	/* Signal starts in oldest bank, but may cross into second oldest bank.
	 * Take the max or the 2 maxs. */
	signal_level = MAX(channel_rssi_history[0], channel_rssi_history[1]) + RSSI_BASE;

	/* Noise is an IIR of averages */
	noise_level = rx->rssi_avg + RSSI_BASE;
	snr = signal_level - noise_level;

	/* Copy 2 banks for analysis */
	for (i = 0; i < 2; i++)
		memcpy(syms + i * BANK_LEN,
		       symbols[(i + 1 + bank) % NUM_BANKS], BANK_LEN);
	
	for (i = 32; i < (BANK_LEN + 32); i++) {
		access_address >>= 1;
		access_address |= (syms[i] << 31);
		if (access_address == 0x8e89bed6) { /* advertising access address */
			systime = time(NULL);
			printf("systime=%u freq=%d addr=%08x clk100ns=%u s=%d n=%d snr=%d\n",
					(int)systime, rx->channel + 2402, access_address,
					clk100ns, signal_level, noise_level, snr);
			/* hard coded to maximum packet length (46) */
			for (j = 0; j < 46; j++) {
				byte = 0;
				for (k = 0; k < 8; k++) {
					byte |= syms[k + (j * 8) + i - 31] << k;
				}
				printf("%02x", byte);
			}
			printf("\n\n");
		}
	}
}
Beispiel #4
0
static void cb_hop(void* args, usb_pkt_rx *rx, int bank)
{
	char syms[BANK_LEN * NUM_BANKS];
	int i, j, k;
	access_code r;
	uint8_t channel;
	uint32_t time; /* in 100 nanosecond units */
	uint8_t clkn_high;
	packet pkt;
	piconet* pn = (piconet *)args;
	uint8_t uap = pn->UAP;

	channel = rx->channel;
	time = letoh32(rx->clk100ns);  /* wire format is le32 */
	clkn_high = rx->clkn_high;
	unpack_symbols(rx->data, symbols[bank]);
	/*
	fprintf(stderr, "rx block timestamp %u * 100 nanoseconds\n", time);
	*/
	/* awfully repetitious */
	k = 0;
	for (i = 0; i < 2; i++)
		for (j = 0; j < BANK_LEN; j++)
			syms[k++] = symbols[(i + 1 + bank) % NUM_BANKS][j];

	r = find_ac(syms, BANK_LEN, pn->LAP);

	if (r.offset > -1) {
		for (i = 2; i < NUM_BANKS; i++)
			for (j = 0; j < BANK_LEN; j++)
				syms[k++] = symbols[(i + 1 + bank) % NUM_BANKS][j];

		init_packet(&pkt, &syms[r.offset], BANK_LEN * NUM_BANKS - r.offset);
		pkt.LAP = r.LAP;
		pkt.clkn = (clkn_high << 19) | ((time + r.offset * 10) / 6250);
		pkt.channel = channel;

		if ((pkt.LAP == pn->LAP) && header_present(&pkt)) {
			printf("\nGOT PACKET on channel %d, LAP = %06x at time stamp %u, clkn %u\n",
			       channel, pkt.LAP, time + r.offset * 10, pkt.clkn);
			if (pn->have_clk6) {
				UAP_from_header(&pkt, pn);
				if (!pn->have_clk6) {
					printf("CLK1-27 discovery failed\n");
					exit(1); /* FIXME */
					winnow(pn);
				}
				if (pn->have_clk27) {
					printf("got CLK1-27\n");
					exit(0);
				}
			} else {
				if (UAP_from_header(&pkt, pn)) {
					if (uap == pn->UAP) {
						printf("got CLK1-6\n");
						init_hop_reversal(0, pn);
						winnow(pn);
					} else {
						printf("failed to confirm UAP\n");
						exit(1);
					}
				}
			}
		}
	}
}
Beispiel #5
0
/* Sniff for LAPs. If a piconet is provided, use the given LAP to
 * search for UAP.
 */
static void cb_lap(void* args, usb_pkt_rx *rx, int bank)
{
	piconet* pn = (piconet *)args;
	char syms[BANK_LEN * NUM_BANKS];
	int i;
	access_code r;
	uint32_t clk100ns; /* in 100 nanosecond units */
	packet pkt;
	char *channel_rssi_history;
	int8_t signal_level;
	int8_t noise_level;
	int8_t snr;
	uint32_t clk0;
	uint32_t clk1;

	/* Sanity check */
	if (rx->channel > (NUM_CHANNELS-1))
		return;

	/* Copy packet (for dump) */
	memcpy(&packets[bank], rx, sizeof(usb_pkt_rx));

	clk100ns = letoh32(rx->clk100ns); /* wire format is le32 */
	/*
	printf("%10u %02x %02d %3.02d %3d %3d %3d\n", rx->clk100ns, rx->status, rx->channel, rx->rssi_min-54, rx->rssi_max-54, rx->rssi_avg-54, rx->rssi_count);
	*/
	unpack_symbols(rx->data, symbols[bank]);

	/* Do analysis based on oldest packet */
	rx = &packets[ (bank+1) % NUM_BANKS ];

	/* Shift rssi max history and append current max */
	channel_rssi_history = rssi_history[rx->channel];
	memmove(channel_rssi_history,
		channel_rssi_history+1,
		RSSI_HISTORY_LEN-1);
	channel_rssi_history[RSSI_HISTORY_LEN-1] = rx->rssi_max;

	/* Signal starts in oldest bank, but may cross into second
	 * oldest bank.  Take the max or the 2 maxs. */
	signal_level = MAX(channel_rssi_history[0], channel_rssi_history[1]) + RSSI_BASE;

	/* Noise is an IIR of averages */
	noise_level = rx->rssi_avg + RSSI_BASE;
	snr = signal_level - noise_level;

	/* Copy 2 banks for analysis */
	for (i = 0; i < 2; i++)
		memcpy(syms + i * BANK_LEN,
		       symbols[(i + 1 + bank) % NUM_BANKS],
		       BANK_LEN);

	/* No piconet given, sniff for any LAP */
	if (pn == NULL) {
		r = sniff_ac(syms, BANK_LEN);
	}
	/* Find packets for specified LAP.  */
	else {
		r = find_ac(syms, BANK_LEN, pn->LAP);
	}

	if ((r.offset > -1) && (r.error_count <= max_ac_errors)) {

		/* Native (Ubertooth) clock with period 312.5 uS. */
		clk0 = (rx->clkn_high << 20)
			+ (rx->clk100ns + r.offset * 10) / 3125;

		/* Bottom clkn bit not needed, clk1 period is 625 uS. */
		clk1 = clk0 / 2;

		/* When reading from file, caller will read
		 * systime before calling this routine, so do
		 * not overwrite. Otherwise, get current time. */
		if ( infile == NULL )
			systime = time(NULL);
		printf("systime=%u ch=%2d LAP=%06x err=%u clk100ns=%u clk1=%u s=%d n=%d snr=%d\n",
		       (int)systime, rx->channel, r.LAP, r.error_count,
		       clk100ns, clk1, signal_level, noise_level, snr);

		/* Found a packet with the requested LAP */
		if (pn != NULL && r.LAP == pn->LAP) {

			/* Determining UAP requires more symbols. Copy
			 * remaining banks. */
			for (i = 2; i < NUM_BANKS; i++)
				memcpy(syms + i * BANK_LEN,
				       symbols[(i + 1 + bank) % NUM_BANKS],
				       BANK_LEN);
			
			init_packet(&pkt, &syms[r.offset],
				    BANK_LEN * NUM_BANKS - r.offset);
			pkt.LAP = r.LAP;
			pkt.clkn = clk1;
			pkt.channel = rx->channel;
			if (header_present(&pkt)) {
				if (UAP_from_header(&pkt, pn))
					exit(0);
			}
		}

		/* If dumpfile is specified, write out all banks to
		 * the file. There could be duplicate data in the dump
		 * if more than one LAP is found within the span of
		 * NUM_BANKS. If experiment mode is selected, extra
		 * info is written out. For now, it just prepends
		 * capture time. */
		if (dumpfile) {
			for(i = 0; i < NUM_BANKS; i++) {
				uint32_t systime_be = htobe32(systime);
				if (fwrite(&systime_be, 
					   sizeof(systime_be), 1,
					   dumpfile)
				    != 1) {;}
				if (fwrite(&packets[(i + 1 + bank) % NUM_BANKS],
					   sizeof(usb_pkt_rx), 1, dumpfile)
				    != 1) {;}
			}
		}
	}
}
Beispiel #6
0
/* Sniff for LAPs. If a piconet is provided, use the given LAP to
 * search for UAP.
 */
static void cb_br_rx(void* args, usb_pkt_rx *rx, int bank)
{
	btbb_packet *pkt = NULL;
	btbb_piconet *pn = (btbb_piconet *)args;
	char syms[BANK_LEN * NUM_BANKS];
	int i;
	int8_t signal_level;
	int8_t noise_level;
	int8_t snr;
	int offset;
	uint32_t clkn;
	uint32_t lap = LAP_ANY;
	uint8_t uap = UAP_ANY;

	/* Sanity check */
	if (rx->channel > (NUM_BREDR_CHANNELS-1))
		goto out;

	/* Copy packet (for dump) */
	memcpy(&usb_packets[bank], rx, sizeof(usb_pkt_rx));

	unpack_symbols(rx->data, br_symbols[bank]);

	/* Do analysis based on oldest packet */
	rx = &usb_packets[ (bank+1) % NUM_BANKS ];
	uint64_t nowns = now_ns_from_clk100ns( rx );

	determine_signal_and_noise( rx, &signal_level, &noise_level );
	snr = signal_level - noise_level;

	/* WC4: use vm circbuf if target allows. This gets rid of this
	 * wrapped copy step. */

	/* Copy 2 oldest banks of symbols for analysis. Packet may
	 * cross a bank boundary. */
	for (i = 0; i < 2; i++)
		memcpy(syms + i * BANK_LEN,
		       br_symbols[(i + 1 + bank) % NUM_BANKS],
		       BANK_LEN);
	
	/* Look for packets with specified LAP, if given. Otherwise
	 * search for any packet.  Also determine if UAP is known. */
	if (pn) {
		lap = btbb_piconet_get_flag(pn, BTBB_LAP_VALID) ? btbb_piconet_get_lap(pn) : LAP_ANY;
		uap = btbb_piconet_get_flag(pn, BTBB_UAP_VALID) ? btbb_piconet_get_uap(pn) : UAP_ANY;
	}

	/* Pass packet-pointer-pointer so that
	 * packet can be created in libbtbb. */
	offset = btbb_find_ac(syms, BANK_LEN, lap, max_ac_errors, &pkt);
	if (offset < 0)
		goto out;

	/* Copy out remaining banks of symbols for full analysis. */
	for (i = 1; i < NUM_BANKS; i++)
		memcpy(syms + i * BANK_LEN,
		       br_symbols[(i + 1 + bank) % NUM_BANKS],
		       BANK_LEN);

	/* Once offset is known for a valid packet, copy in symbols
	 * and other rx data. CLKN here is the 312.5us CLK27-0. The
	 * btbb library can shift it be CLK1 if needed. */
	clkn = (rx->clkn_high << 20) + (le32toh(rx->clk100ns) + offset + 1562) / 3125;
	btbb_packet_set_data(pkt, syms + offset, NUM_BANKS * BANK_LEN - offset,
			   rx->channel, clkn);

	/* Dump to PCAP/PCAPNG if specified */
#if defined(USE_PCAP)
        if (h_pcap_bredr) {
		btbb_pcap_append_packet(h_pcap_bredr, nowns,
					signal_level, noise_level,
					lap, uap, pkt);
        }
#endif
	if (h_pcapng_bredr) {
		btbb_pcapng_append_packet(h_pcapng_bredr, nowns, 
					  signal_level, noise_level,
					  lap, uap, pkt);
	}

	/* When reading from file, caller will read
	 * systime before calling this routine, so do
	 * not overwrite. Otherwise, get current time. */
	if (infile == NULL)
		systime = time(NULL);

	/* If dumpfile is specified, write out all banks to the
	 * file. There could be duplicate data in the dump if more
	 * than one LAP is found within the span of NUM_BANKS. */
	if (dumpfile) {
		for(i = 0; i < NUM_BANKS; i++) {
			uint32_t systime_be = htobe32(systime);
			if (fwrite(&systime_be, 
				   sizeof(systime_be), 1,
				   dumpfile)
			    != 1) {;}
			if (fwrite(&usb_packets[(i + 1 + bank) % NUM_BANKS],
				   sizeof(usb_pkt_rx), 1, dumpfile)
			    != 1) {;}
		}
	}

	printf("systime=%u ch=%2d LAP=%06x err=%u clk100ns=%u clk1=%u s=%d n=%d snr=%d\n",
	       (int)systime,
	       btbb_packet_get_channel(pkt),
	       btbb_packet_get_lap(pkt),
	       btbb_packet_get_ac_errors(pkt),
	       rx->clk100ns,
	       btbb_packet_get_clkn(pkt),
	       signal_level,
	       noise_level,
	       snr);

	i = btbb_process_packet(pkt, pn);
	if(i < 0) {
		follow_pn = pn;
		stop_ubertooth = 1;
	}

out:
	if (pkt)
		btbb_packet_unref(pkt);
}