Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Jan 2013 21:42:31 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r245182 - user/adrian/ath_radar_stuff/src/spectral_fft
Message-ID:  <201301082142.r08LgVYL015772@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Jan  8 21:42:30 2013
New Revision: 245182
URL: http://svnweb.freebsd.org/changeset/base/245182

Log:
  Biiig fft eval commit:
  
  * Hard-code the fft source to an AR9280 on wlan0 for now, sorry!
  * Change the pcap code to be:
    + a data source;
    + that runs in a thread;
    + and calls a cb on each radar entry decoded;
  
  * Modify the rendering code to use the fft histogram, rather than
    a list of frames to render;
  * Populate the histogram via a cb, with relevant locking;
  * never wait/delay, always just poll for events.
  
  I'm not doing correct locking or conditional wakeups _at all_ in the
  rendering loop as this is quite honestly a terrible piece of code.
  But it's good enough to do initial test rendering with.

Modified:
  user/adrian/ath_radar_stuff/src/spectral_fft/Makefile
  user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c
  user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.c
  user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.h

Modified: user/adrian/ath_radar_stuff/src/spectral_fft/Makefile
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/Makefile	Tue Jan  8 21:40:21 2013	(r245181)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/Makefile	Tue Jan  8 21:42:30 2013	(r245182)
@@ -1,10 +1,10 @@
 PROG=	fft_eval
 
-SRCS=	fft_eval.c fft_linux.c fft_freebsd.c
+SRCS=	fft_eval.c fft_freebsd.c fft_histogram.c
 
-CFLAGS+=	-I/usr/local/include -L/usr/local/lib -I../../lib/ -L../../lib/libradarpkt
+CFLAGS+=	-I/usr/local/include -L/usr/local/lib -I../../lib/ -L../../lib/libradarpkt -pthread
 
-LDADD+=	-lSDL -lSDL_ttf -lradarpkt -lpcap
+LDADD+=	-lSDL -lSDL_ttf -lradarpkt -lpcap -pthread
 
 NO_MAN=	1
 

Modified: user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c	Tue Jan  8 21:40:21 2013	(r245181)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c	Tue Jan  8 21:42:30 2013	(r245182)
@@ -27,18 +27,32 @@
 #include <errno.h>
 #include <stdio.h>
 #include <math.h>
+#include <pcap.h>
+#include <pthread.h>
+#include <unistd.h>
+
 #include <SDL/SDL.h>
 #include <SDL/SDL_ttf.h>
 
 #include "fft_eval.h"
-#include "fft_linux.h"
+
+#include "net80211/ieee80211.h"
+#include "net80211/ieee80211_radiotap.h"
+
+#include "libradarpkt/pkt.h"
+#include "libradarpkt/ar5212_radar.h"
+#include "libradarpkt/ar5416_radar.h"
+#include "libradarpkt/ar9280_radar.h"
+
+#include "fft_eval.h"
 #include "fft_freebsd.h"
+#include "fft_histogram.h"
 
 #define WIDTH	1600
 #define HEIGHT	650
 #define BPP	32
 
-#define X_SCALE	10
+#define X_SCALE	5
 #define Y_SCALE	4
 
 #define	RMASK 	0x000000ff
@@ -49,11 +63,12 @@
 #define	BBITS	16
 #define	AMASK	0xff000000
 
+/* XXX ew globals */
+pthread_mutex_t mtx_histogram;
+int g_do_update = 0;
 
 SDL_Surface *screen = NULL;
 TTF_Font *font = NULL;
-struct scanresult *result_list;
-int scanresults_n = 0;
 
 int graphics_init_sdl(void)
 {
@@ -116,7 +131,7 @@ int pixel(Uint32 *pixels, int x, int y, 
 }
 
 
-#define SIZE 3
+#define SIZE 2
 /* this function blends a 2*SIZE x 2*SIZE blob at the given position with
  * the defined opacity. */
 int bigpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
@@ -186,7 +201,7 @@ int draw_picture(int highlight, int star
 			pixels[x + y * WIDTH] = AMASK;
 
 	/* vertical lines (frequency) */
-	for (i = 2300; i < 6000; i += 10) {
+	for (i = 2300; i < 6000; i += 20) {
 		x = (X_SCALE * (i - startfreq));
 
 		if (x < 0 || x > WIDTH)
@@ -210,53 +225,26 @@ int draw_picture(int highlight, int star
 		render_text(surface, text, 5, y - 15);
 	}
 
+	/* Render 2300 -> 6000 in 1MHz increments, but using KHz math */
+	/* .. as right now the canvas is .. quite large. */
+	for (i = 2300*1000; i < 6000*1000; i+= 250) {
+		float signal;
+		int freqKhz = i;
 
-	rnum = 0;
-	for (result = result_list; result ; result = result->next, rnum++) {
+		/* Fetch dBm value at the given frequency in KHz */
+		signal = (float) fft_fetch_freq(freqKhz);
+		x = X_SCALE * (freqKhz - (startfreq * 1000)) / 1000;
 
-		if (rnum != highlight)
-			continue;
+		y = 400 - (400.0 + Y_SCALE * signal);
 
-		if (rnum == highlight) {
-			/* prints some statistical data about the currently selected 
-			 * data sample and auxiliary data. */
-			printf("result[%03d]: freq %04d rssi %03d, noise %03d, max_magnitude %04d max_index %03d bitmap_weight %03d tsf %llu\n",
-				rnum, result->sample.freq, result->sample.rssi, result->sample.noise,
-				result->sample.max_magnitude, result->sample.max_index, result->sample.bitmap_weight,
-				result->sample.tsf);
-			highlight_freq = result->sample.freq;
-		}
+		color = RMASK | AMASK;
+		opacity = 255;
 
-		for (i = 0; i < SPECTRAL_HT20_NUM_BINS; i++) {
-			float freq;
-			float signal;
-			int data;
-			freq = result->sample.freq - 10.0 + ((20.0 * i) / SPECTRAL_HT20_NUM_BINS);
-			
-			x = (X_SCALE * (freq - startfreq));
-
-			/* This is where the "magic" happens: interpret the signal
-			 * to output some kind of data which looks useful.  */
-
-			signal = result->sample.data[i];
-			printf("  signal[%d]: %f\n", i, signal);
-			if (signal == 0)
-				signal = 1;
-
-			y = 400 - (400.0 + Y_SCALE * signal);
-
-			if (rnum == highlight) {
-				color = RMASK | AMASK;
-				opacity = 255;
-			} else {
-				color = BMASK | AMASK;
-				opacity = 30;
-			}
+//		printf("  (%d) %d,%d\n", freqKhz, x, y);
 
-			if (bigpixel(pixels, x, y, color, opacity) < 0)
-				continue;
+		if (bigpixel(pixels, x, y, color, opacity) < 0)
+			continue;
 
-		}
 	}
 
 	SDL_BlitSurface(surface, NULL, screen, NULL);
@@ -285,6 +273,13 @@ void graphics_main(void)
 	}
 	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
 	while (!quit) {
+		pthread_mutex_lock(&mtx_histogram);
+		if (g_do_update == 1) {
+			change = 1;	/* XXX always render */
+			g_do_update = 0;
+		}
+		pthread_mutex_unlock(&mtx_histogram);
+
 		if (change) {
 			highlight_freq = draw_picture(highlight, startfreq);
 			change = 0;
@@ -305,10 +300,10 @@ void graphics_main(void)
 				accel = 100;
 		}
 
-		if (accel)
+//		if (accel)
 			SDL_PollEvent(&event);
-		else
-			SDL_WaitEvent(&event);
+//		else
+//			SDL_WaitEvent(&event);
 
 		switch (event.type) {
 		case SDL_QUIT:
@@ -316,6 +311,7 @@ void graphics_main(void)
 			break;
 		case SDL_KEYDOWN:
 			switch (event.key.keysym.sym) {
+#if 0
 			case SDLK_LEFT:
 				if (highlight > 0) {
 					highlight--;
@@ -330,6 +326,7 @@ void graphics_main(void)
 					change = 1;
 				}
 				break;
+#endif
 			case SDLK_PAGEUP:
 				accel-= 2;
 				scroll = 1;
@@ -375,8 +372,25 @@ void usage(int argc, char *argv[])
 
 }
 
+static void
+fft_eval_cb(struct radar_entry *re, void *cbdata)
+{
+	struct radar_fft_entry *fe;
+	int i;
+
+	pthread_mutex_lock(&mtx_histogram);
+	for (i = 0; i < re->re_num_spectral_entries; i++) {
+		fft_add_sample(re, &re->re_spectral_entries[i]);
+	}
+	g_do_update = 1;
+	pthread_mutex_unlock(&mtx_histogram);
+
+}
+
 int main(int argc, char *argv[])
 {
+	int ret;
+
 	if (argc < 2) {
 		usage(argc, argv);
 		return -1;
@@ -384,8 +398,15 @@ int main(int argc, char *argv[])
 
 	fprintf(stderr, "WARNING: Experimental Software! Don't trust anything you see. :)\n");
 	fprintf(stderr, "\n");
-	scanresults_n = read_scandata_freebsd(argv[1], &result_list);
-	if (scanresults_n < 0) {
+
+	/* Setup radar entry callback */
+	pthread_mutex_init(&mtx_histogram, NULL);
+	set_scandata_callback(fft_eval_cb, NULL);
+
+	/* Fetch data */
+	ret = read_scandata_freebsd(argv[1], NULL);
+
+	if (ret < 0) {
 		fprintf(stderr, "Couldn't read scanfile ...\n");
 		usage(argc, argv);
 		return -1;

Modified: user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.c
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.c	Tue Jan  8 21:40:21 2013	(r245181)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.c	Tue Jan  8 21:42:30 2013	(r245182)
@@ -1,8 +1,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <err.h>
+#include <unistd.h>
 #include <string.h>
 #include <netinet/in.h>	/* for ntohl etc */
+#include <pthread.h>
 
 #include <pcap.h>
 
@@ -17,12 +19,18 @@
 #include "fft_eval.h"
 #include "fft_freebsd.h"
 
-/*
- * XXX ew, static variables
- */
-int n_spectral_samples = 0;
-struct scanresult **result_head;
-struct scanresult *result_tail;
+static scandata_cb cb_cb = NULL;
+static void * cb_cbdata = NULL;
+pthread_t main_pthread;
+pcap_t * g_p;
+int g_chip = 0;
+
+void
+set_scandata_callback(scandata_cb cb, void *cbdata)
+{
+	cb_cb = cb;
+	cb_cbdata = cbdata;
+}
 
 /*
  * Compile up a rule that's bound to be useful - it only matches on
@@ -31,7 +39,6 @@ struct scanresult *result_tail;
  * tcpdump -ni wlan0 -y IEEE802_11_RADIO -x -X -s0 -v -ve \
  *    'radio[73] == 0x2 && (radio[72] == 5 || radio[72] == 24)
  */
-
 #define	PKTRULE "radio[73] == 0x2 && (radio[72] == 5 || radio[72] == 24)"
 
 static int
@@ -45,42 +52,14 @@ pkt_compile(pcap_t *p, struct bpf_progra
 static void
 pkt_handle_single(struct radar_entry *re)
 {
-	int i, j;
-	struct scanresult *result;
+	/* Call our callback w/ the radar entry */
+	if (cb_cb)
+		cb_cb(re, cb_cbdata);
 
-	for (i = 0; i < re->re_num_spectral_entries; i++) {
-		result = malloc(sizeof(*result));
-		if (result == NULL) {
-			/* Skip on malloc failure */
-			warn("%s: malloc", __func__);
-			continue;
-		}
-
-		/* Fill out the result, assuming HT20 for now */
-		result->sample.tlv.type = ATH_FFT_SAMPLE_HT20;
-		result->sample.tlv.length = sizeof(result->sample);	/* XXX right? */
-
-		result->sample.freq = re->re_freq;
-		result->sample.rssi = re->re_rssi;
-		result->sample.noise = -95;	/* XXX extract from header */
-		result->sample.max_magnitude = re->re_spectral_entries[i].pri.max_magnitude;
-		result->sample.max_index = re->re_spectral_entries[i].pri.max_index;
-		result->sample.bitmap_weight = re->re_spectral_entries[i].pri.bitmap_weight;
-		/* XXX no max_exp? */
-		result->sample.tsf = re->re_timestamp;
-		/* XXX 56 = numspectralbins */
-		for (j = 0; j < 56; j++) {
-			result->sample.data[j] = re->re_spectral_entries[i].pri.bins[j].dBm;
-		}
-
-		/* add it to the list */
-		if (result_tail)
-			result_tail->next = result;
-		else
-			(*result_head) = result;
-		result_tail = result;
-		n_spectral_samples++;
-	}
+#if 0
+	/* Sleep for a bit */
+	usleep(100 * 1000);	/* 100ms */
+#endif
 }
 
 static void
@@ -211,23 +190,44 @@ usage(const char *progname)
 	    progname);
 }
 
-int
-open_device(const char *dev_str, const char *chip_str, const char *mode)
+static void *
+fft_pcap_thread_main(void *arg)
 {
-	char *dev;
-	pcap_t * p;
-	const char *fname;
 	const unsigned char *pkt;
 	struct pcap_pkthdr *hdr;
 	int len, r;
-	int chip = 0;
 
+	/*
+	 * Iterate over frames, looking for radiotap frames
+	 * which have PHY errors.
+	 *
+	 * XXX We should compile a filter for this, but the
+	 * XXX access method is a non-standard hack atm.
+	 */
+	while ((r = pcap_next_ex(g_p, &hdr, &pkt)) >= 0) {
+#if 0
+		printf("capture: len=%d, caplen=%d\n",
+		    hdr->len, hdr->caplen);
+#endif
+		if (r > 0)
+			pkt_handle(g_chip, pkt, hdr->caplen);
+	}
+
+	return (NULL);
+}
+
+
+int
+open_device(const char *dev_str, const char *chip_str, const char *mode)
+{
+	char *dev;
+	const char *fname;
 	if (strcmp(chip_str, "ar5212") == 0) {
-		chip = CHIP_AR5212;
+		g_chip = CHIP_AR5212;
 	} else if (strcmp(chip_str, "ar5416") == 0) {
-		chip = CHIP_AR5416;
+		g_chip = CHIP_AR5416;
 	} else if (strcmp(chip_str, "ar9280") == 0) {
-		chip = CHIP_AR9280;
+		g_chip = CHIP_AR9280;
 	} else {
 		usage("main");
 		exit(255);
@@ -237,35 +237,24 @@ open_device(const char *dev_str, const c
 	fname = dev_str;
 
 	if (strcmp(mode, "file") == 0) {
-		p = open_offline(fname);
+		g_p = open_offline(fname);
 	} else if (strcmp(mode, "if") == 0) {
-		p = open_online(fname);
+		g_p = open_online(fname);
 	} else {
 		usage("main");
 		exit(255);
 	}
 
-	if (p == NULL)
+	if (g_p == NULL)
 		exit(255);
 
-	/*
-	 * Iterate over frames, looking for radiotap frames
-	 * which have PHY errors.
-	 *
-	 * XXX We should compile a filter for this, but the
-	 * XXX access method is a non-standard hack atm.
-	 */
-	while ((r = pcap_next_ex(p, &hdr, &pkt)) >= 0) {
-#if 0
-		printf("capture: len=%d, caplen=%d\n",
-		    hdr->len, hdr->caplen);
-#endif
-		if (r > 0)
-			pkt_handle(chip, pkt, hdr->caplen);
+	/* Create data source thread */
+	if (pthread_create(&main_pthread, NULL,
+	    fft_pcap_thread_main, NULL) != 0) {
+		warnx("pthread_create");
+		return(-1);
 	}
 
-	pcap_close(p);
-
 	/* XXX for now */
 	return (0);
 }
@@ -274,13 +263,6 @@ int
 read_scandata_freebsd(char *fname, struct scanresult **result)
 {
 
-	/* XXX for now, return/do nothing */
-
-	n_spectral_samples = 0;
-	result_head = result;
-	result_tail = (*result);
-
-	(void) open_device(fname, "ar9280", "file");
-
-	return n_spectral_samples;
+	(void) open_device("wlan0", "ar9280", "if");
+	return (0);
 }

Modified: user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.h
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.h	Tue Jan  8 21:40:21 2013	(r245181)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/fft_freebsd.h	Tue Jan  8 21:42:30 2013	(r245182)
@@ -1,6 +1,9 @@
 #ifndef	__FFT_FREEBSD_H__
 #define	__FFT_FREEBSD_H__
 
+typedef	void (* scandata_cb)(struct radar_entry *re, void *cbdata);
+
+extern	void set_scandata_callback(scandata_cb cb, void *cbdata);
 extern	int read_scandata_freebsd(char *fname, struct scanresult **result);
 
 #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301082142.r08LgVYL015772>