#!/usr/bin/perl # GPL V2 or greater # Used to control the 4 led's on ubiquti for device aiming. # Written by Conrad Lara KG6JEI sub aimmode_printusage{ print "USAGE:\n"; print "$0 SSID\n"; die; } # SSID NAME if ( $ARGV[0] ) { $SSIDName= lc $ARGV[0]; } else { $SSIDName= lc "BroadbandHamnet-v2"; } $lastset=0; $lastval=0; #dbm values for each RSSI trigger level $RSSI_4=-45; $RSSI_3=-55; $RSSI_2=-65; $RSSI_1=-75; # LED Set Wrappe sub SetLED { ($fh, $state ) = @_ ; print $fh $state ; binmode($fh); } # Reset LED's to baseline sub init_led_triggers { open ( LINK4_trigger,'>/sys/class/leds/ubnt:green:link4/trigger'); open ( LINK3_trigger,'>/sys/class/leds/ubnt:green:link3/trigger'); open ( LINK2_trigger,'>/sys/class/leds/ubnt:orange:link2/tigger'); open ( LINK1_trigger,'>/sys/class/leds/ubnt:red:link1/trigger'); print LINK4_trigger "none"; print LINK3_trigger "none"; print LINK2_trigger "none"; print LINK1_trigger "none"; close ( LINK4_trigger); close ( LINK3_trigger); close ( LINK2_trigger); close ( LINK1_trigger); } sub aimmode_start { # Prep the system system('/etc/init.d/linkled stop'); system('/etc/init.d/olsrd stop'); system('/sbin/ifdown wifi'); system('/sbin/ifdown wifi_mon'); system('/usr/sbin/iw phy phy0 interface add mon0 type monitor'); system('/usr/sbin/iw dev mon0 set channel 1'); system('/sbin/ifconfig mon0 up'); #Open up the files we will need to run with # Run tcpdump in buffered (-l) mode so each line returns with a newline open ( $TCPDUMP,"/usr/sbin/tcpdump -l -i mon0 \"link[0] == 0x80\" |"); open ( $LINK4_led,'>/sys/class/leds/ubnt:green:link4/brightness'); open ( $LINK3_led,'>/sys/class/leds/ubnt:green:link3/brightness'); open ( $LINK2_led,'>/sys/class/leds/ubnt:orange:link2/brightness'); open ( $LINK1_led,'>/sys/class/leds/ubnt:red:link1/brightness'); } sub aimmode_shutdown { #Turn off all LED's except LINk4 SetLED ($LINK4_led, 1); SetLED ($LINK3_led, 0); SetLED ($LINK2_led, 0); SetLED ($LINK1_led, 0); close ($TCPDUMP); close ($LINK4_led); close ($LINK3_led); close ($LINK2_led); close ($LINK1_led); # Brining up wifi is a bit more complicated than just ifconfig up so we let `ifup` handle it ... takes a bit to finish so sleep 10s system('ifup wifi'); system('ifup wifi_mon'); print "Please wait while we restart the services"; sleep 10; system('/etc/init.d/olsrd start'); system('/etc/init.d/linkled start'); } init_led_triggers(); $SIG{INT} = sub { aimmode_shutdown(); exit; }; aimmode_start(); # Main while loop while ( <$TCPDUMP> ) { next unless /.* ([\d\-]+)dB.*Beacon \((.*)\)/; next unless lc $2 eq $SSIDName ; #Average the last value and this values in order to tame sudden spikes $s=int(($1+$lastvalue)/2); print "$s \n"; if ($s >= $RSSI_4 ) { SetLED ($LINK4_led, 1); } else { SetLED ($LINK4_led, 0); } if ($s >= $RSSI_3 ) { SetLED ($LINK3_led, 1); } else { SetLED ($LINK3_led, 0); } if ($s >= $RSSI_2 ) { SetLED ($LINK2_led, 1); } else { SetLED ($LINK2_led, 0); } if ($s >= $RSSI_1 ) { SetLED ($LINK1_led, 1); } else { SetLED ($LINK1_led, 0); } $lastvalue=$s; } # Normally the SIG{INT} handler will be done before here # But in case the TCPDUMP dies out we want to reset the system aimmode_shutdown();