ok, put your geek hat on ...
For position mapping, check out a perl module
perl-gps to interface with Garmin GPS units through a serial port.
For signal strength monitoring, combine this with Linux's iwconfig + iwspy (already part of most modern dists) or BSD's wicontrol wireless utility.
Sniffing the wireless interface via tcpdump and parsing/greping through a perl scipt will do it.
Evil Pete pushed the perl script below (for BSD - also easy to port to use linux wtools) to the BAWUG list: It monitors signal strength vs. GPS positioning. It should be fairly easy to hack this to monitor singal strengths of all wireless nodes detected via tcpdump'ing.
more soon on this as I hack the script for Linux - post your comments and adventures here too ...
.vortex
Evil Pete's BSD perl script:
#!/usr/bin/perl
#
# requires p5-GPS (freebsd:/usr/ports/astro/p5-GPS )
# this is tested with a Garmin eMAP
#
# Todo:
# reset card to the way we found it?
# not print repeating data
#use strict;
use GPS::Garmin;
#init shit
$|=1;
my $shutoff_GPS = 0; # my cause a error, pitty there is no way to power on.
my $use_gps = 1;
#my $gps_device = "/dev/ttyd0";
my $gps_device = "/dev/cuaa0";
my $delay = 5; # seconds
my $wicomm = '/usr/sbin/wicontrol';
my $gps;
my ($save_station_name, $save_desired_name, $save_mac_addr);
my ($save_power_mgmt, $save_web_crypt, $save_port_type);
#--
sub save_card_conf {
open(WICO, "$wicomm|") or die "$wicomm Error: $!";
while () {
chomp;
$save_station_name = $1 if /^Station name:\s+\[(.*)\]$/;
$save_desired_name = $1 if /^Desired netname.*\[(.*)\]$/;
$save_mac_addr = $1 if /^MAC address:\s+\[(.*)\]$/;
$save_power_mgmt = $1 if /^Power Mgmt.*\s+\[(.*)\]$/;
$save_web_crypt = $1 if /^WEP encryption:\s+\[(.*)\]$/;
$save_port_type = $1 if /^Port type.*\s+\[(.*)\]$/;
}
close (WICO);
if ($save_web_crypt =~ /Off/) {
$save_web_crypt = 0;
} else {
$save_web_crypt = 1;
}
#$save_desired_name = "ANY" if ($save_desired_name =~ /^\s+$/) ;
$save_desired_name = "" if ($save_desired_name =~ /^\s+$/) ;
#print "save_station_name \"$save_station_name\"\n";
#print "save_desired_name \"$save_desired_name\"\n";
#print "save_mac_addr \"$save_mac_addr\"\n";
#print "save_power_mgmt \"$save_power_mgmt\"\n";
#print "save_web_crypt \"$save_web_crypt\"\n";
#print "save_port_type \"$save_port_type\"\n";
return;
}
sub initialize {
print "Initializing....\n";
print "\tSaving WLAN card configuration\n";
save_card_conf;
$SIG{'INT'} = "shut_it_down";
$SIG{'QUIT'} = "shut_it_down";
print "\treconfigurating WLAN card\n";
system("$wicomm -n \"\""); # "ANY" should work but it dont
system("$wicomm -s 'WLAN Scan'"); # Better the the default
system("$wicomm -p1"); # Port type BSS
system("$wicomm -P0"); # no power save
system("$wicomm -e0"); # no encryption
system("$wicomm -m DE:AD:DE:AD:DE:AD"); # humor me...
# Sadly we can't just probe to see if there is a GPS attached
# the library will call "die()" for us if it fails..
if ($use_gps) {
print "\tAccessing GPS....\n";
$gps= new GPS::Garmin ( 'Port' => $gps_device,
'Baud' => 9600,
) or warn "Unable to connect to GPS receiver: $!";
}
print "\tDone.\n";
return;
}
sub print_header {
my ($sec,$min,$hour,$mday,$mon,$year);
my ($prod_id, $soft_ver, $prod_desc);
print "My Info:\n\t";
open(WICO, "$wicomm|") or die "$wicomm Error: $!";
while () {
chomp;
print "Name=\"",$1,"\"\t" if /^Station name:\s+\[(.*)\]$/;
print "MAC=",$1,"\t" if /^MAC address:\s+\[(.*)\]$/;
print "Serial=",$1,"\t" if /^NIC serial number.*\[(.*)\]$/;
#print $1,"\t" if /^Comms.*\[(.*)\]$/;
}
close(WICO);
print "\n";
if ($use_gps) {
($prod_id, $soft_ver, $prod_desc) = $gps->get_product_id;
print "GPS Info:\n\t$prod_id\t$soft_ver\t$prod_desc\n\n";
print "Current Time GPS/SYS (GMT):\t";
($sec,$min,$hour,$mday,$mon,$year) = $gps->get_time;
print "$hour\:$min\:$sec\t";
} else {
print "NO GPS\t";
}
($sec,$min,$hour,$mday,$mon,$year) = gmtime(time);
printf "%2.2d:%2.2d:%2.2d\n", $hour, $min, $sec;
print "\n\n\n\n";
return;
}
sub scan {
my ($netname, $curr_bssid, $comm_stat, $ap_density, $port_type);
my ($latsign,$lat,$lnsign,$lon) = 0;
my ($sec,$min,$hour,$mday,$mon,$year);
while (1) {
$netname = $curr_bssid = $comm_stat = $ap_density = "";
open(WICO, "$wicomm|") or die "$wicomm Error: $!";
while () {
chomp;
$netname = $1 if /^Current netname \(SSID\):\s+\[(.*)\]$/;
$curr_bssid = $1 if /^Current BSSID:\s+\[(.*)\]$/;
$comm_stat = $1 if /^Comms.*\[(.*)\]$/;
$ap_density = $1 if /^Access point.*\[(.*)\]$/;
$port_type = $1 if /^Port type.*\s+\[(.*)\]$/;
}
close (WICO);
if (( $curr_bssid =~ /44:44:44:44:44:44/) || ( length($curr_bssid) == 0 )) {
print "<",$curr_bssid,">\t";
#print "44 MAC\n" if ( $curr_bssid =~ /^44:44:44:44:44:44/) ;
#print "NULL Id\n" if ( length($curr_bssid) == 0 );
print "SKIPPED\n\n";
} else {
if ($use_gps) {
($latsign,$lat,$lnsign,$lon) = $gps->get_position;
}
printf "$latsign %4.9f \t $lnsign %4.9f", $lat, $lon;
print "\t($netname)\n";
print "\t", ($port_type == 1 ? "BBS" : "ad-hoc") ;
print "\t(",$curr_bssid,")";
print "\n";
#($sec,$min,$hour,$mday,$mon,$year) = $gps->get_time;
($sec,$min,$hour,$mday,$mon,$year) = gmtime(time);
printf "\t%2.2d:%2.2d:%2.2d (GMT)", $hour, $min, $sec;
print "\t",$comm_stat;
#print "\t",$ap_density;
print "\n\n";
}
system("$wicomm -p1"); # reset the SSID?
sleep $delay;
}
}
sub restore_card_conf{
print "Restoring card conf\n";
system("$wicomm -n \"$save_desired_name\"");
system("$wicomm -s \"$save_station_name\"");
system("$wicomm -p$save_port_type");
system("$wicomm -P$save_power_mgmt");
system("$wicomm -e$save_web_crypt");
system("$wicomm -m $save_mac_addr");
print "save_station_name \"$save_station_name\"\n";
print "save_desired_name \"$save_desired_name\"\n";
print "save_mac_addr \"$save_mac_addr\"\n";
print "save_power_mgmt \"$save_power_mgmt\"\n";
print "save_web_crypt \"$save_web_crypt\"\n";
print "save_port_type \"$save_port_type\"\n";
return;
}
sub clean_up {
restore_card_conf;
if ($shutoff_GPS > 0) {
print "powering GPS down\n";
$gps->power_off;
}
}
sub shut_it_down {
print "shutting down\n";
clean_up;
exit;
}
sub main {
initialize;
print_header;
scan;
clean_up;
exit(0);
}
main;
exit;