r4893 - in developers/werner/wlan: . freeze
werner at docs.openmoko.org
werner at docs.openmoko.org
Thu Jan 22 03:49:43 CET 2009
Author: werner
Date: 2009-01-22 03:49:42 +0100 (Thu, 22 Jan 2009)
New Revision: 4893
Added:
developers/werner/wlan/freeze/
developers/werner/wlan/freeze/README
developers/werner/wlan/freeze/r1.pl
developers/werner/wlan/freeze/r2.pl
developers/werner/wlan/freeze/tst
Log:
Collection of scripts to try to reproduce the frozen station list and to
analyze the results.
Added: developers/werner/wlan/freeze/README
===================================================================
--- developers/werner/wlan/freeze/README (rev 0)
+++ developers/werner/wlan/freeze/README 2009-01-22 02:49:42 UTC (rev 4893)
@@ -0,0 +1,118 @@
+Test setup:
+
+- Access point running OpenWrt "Kamikaze" or compatible
+
+- Give the Neo password-less SSH access to the access point, e.g., with
+
+ host# scp .ssh/id_rsa.pub neo:.ssh/
+ host# scp .ssh/id_rsa.pub access-point:/etc/dropbear/authorized_keys
+
+- The Neo must be able to connect to the access point over USB without
+ relying on a default route. This can be accomplished by port forwarding
+ on the host to which the Neo's USB is connected:
+
+ host# ssh -L *:2222:localhost:22 access-point
+
+- Boot the Neo, wait until the system has settled, then connect to the
+ serial console and log all the output:
+
+ host# neocon -T -l log -t 10 /dev/ttyUSB{1,2,3}
+
+ The -T option is optional. The timestamps may be used for further
+ analysis in the future.
+
+ It is important that this includes all printks. If necessary, increase
+ the loglevel with
+
+ neo# dmesg -n 8
+
+- Edit the configuration variables at the beginning of "tst".
+
+- Copy the test script to the Neo and run the test:
+
+ host# cp tst neo:
+ neo# ./tst
+
+ Optionally, the number of test runs can be passed as an argument to
+ "tst". 100 rounds take roughly one hour.
+
+
+What the test script does:
+
+- It simulates roaming by changing the frequency of the access point
+
+- Before each frequency change, connectivity is checked by pinging the
+ access point. Then, after the change, connectivity is checked again.
+
+- In case of a communication failure before the frequency change, the
+ WLAN module is reset and a new test round is started.
+
+- In case of a communication failure after the frequency change, one
+ of the following three resolution strategies is randomly selected:
+
+ 1) Perform an access point scan. If this is unsuccessful, perform
+ two scans in a row. Then three.
+
+ 2) Re-issue the iwconfig command to configure the WLAN interface,
+ thereby manually forcing a re-association.
+
+ 3) Remain idle for a random amount of time, up to five minutes,
+ then try communicating again. Repeat up to three times.
+
+ If the resolution is unsuccessful, do three times "iwlist scan",
+ reset the interface, then start a new round.
+
+
+The data we collect:
+
+- Kernel messages to track the state of the WLAN module
+
+- Many "iwlist scan" results. A telltale sign of the frozen access point
+ list problem is that only the access point we previously associated
+ with remains on the list and subsequent attempts to "iwlist scan" are
+ ignored.
+
+- Detailed ping results. Some abnormal situations may cause marginal
+ performance without not breaking communication completely. We keep the
+ data for later mining.
+
+
+Evaluation:
+
+- There are about 10kB of log data per round. The script r1.pl extracts
+ all state transitions and the most important events, and outputs them
+ in the following normalized format:
+
+ <type> <parameter> ...
+
+ Examples:
+
+ - STATE HOP 1 to 11
+ A frequency change from channels 1 to 11 is being attempted. Channel
+ 1 is at 2412MHz.
+
+ - STATE ASSOC 6
+ WLAN has associated to the currently selected channel.
+
+ - STATE LATE 10
+ WLAN has associated to the previously selected channel.
+
+ - STATE WRONG 8
+ WLAN has associated to a channel that's neither the current nor the
+ previous.
+
+ - TIME 949864524
+ Timestamp, seconds since the beginning of the epoch. (In this example,
+ with a clock that's off by a few years :)
+
+- The script r2.pl further condenses the information into the chain of
+ events of individual runs, one run per line. The output can be modified
+ with the following options:
+
+ -v include some parameters, such as the round number
+ -t prefix each chain with the number of seconds it took till the next
+ round
+
+- Chains can be sorted by frequency with:
+
+ ./r1.pl log | ./r2.pl | sort | uniq -c | sort -rn
Added: developers/werner/wlan/freeze/r1.pl
===================================================================
--- developers/werner/wlan/freeze/r1.pl (rev 0)
+++ developers/werner/wlan/freeze/r1.pl 2009-01-22 02:49:42 UTC (rev 4893)
@@ -0,0 +1,168 @@
+#!/usr/bin/perl
+#
+# r1.pl - reductor #1
+#
+# This reductor performs the following operations on a test session log:
+#
+# - remove "noise" messages
+# - compact ping and iwconfig sessions
+# - normalize state messages
+#
+
+
+$strict = 0; # fail if input is incomprehensible
+
+$cc = 1; # current channel
+$pc = undef; # previous channel
+undef $special; # special parser state
+
+
+sub scan
+{
+ local ($t) = @_;
+
+ if ($t =~ /^\s*$/) {
+ print "SCAN $tmp\n";
+ undef *special;
+ return;
+ }
+ if ($t =~ /ESSID:"([^"]*)"/) {
+ $tmp .= " " if defined $tmp;
+ $tmp .= $1;
+ return;
+ }
+ if ($t =~ /Frequency:.*Channel (\d+)/) {
+ # Note: when in trouble, the channel number may be reported as 0 !
+ $c = $1;
+ if ($c == $cc) {
+ $tmp .= "(cur)";
+ } elsif ($c == $pc) {
+ $tmp .= "(last)";
+ } else {
+ $tmp .= "($c)";
+ }
+ return;
+ }
+}
+
+
+sub ping
+{
+ local ($t) = @_;
+
+ return if $t =~ /^64 bytes/;
+ return if $t =~ /^\s*$/;
+ return if $t =~ /^--- 192/;
+ if ($t =~ /^ping: sendmsg/) {
+ $tmp = "E ";
+ return;
+ }
+ if ($t =~ /^(\d+) packets transmitted, (\d+) received/) {
+ $tmp .= "$1/$2";
+ if (!$2) {
+ print "PING $tmp\n";
+ undef *special;
+ }
+ return;
+ }
+ if ($t =~ /^rtt[^,]*/) {
+ print "PING $tmp $&\n";
+ undef *special;
+ return;
+ }
+ die;
+}
+
+
+$scan = $ping = 1;
+
+while (1) {
+ $l = <>;
+ last unless defined $l;
+ $l =~ s/^\d+\.\d+ //;
+ if (defined $back) {
+ $l = $back.$l;
+ undef $back;
+ }
+ next if $l =~ /^\+/;
+
+ # asynchronous notifications
+
+ if ($l =~ /\[[^]]+\] (.*)\n/) {
+ $back = $`;
+ $t = $1;
+ next if $t =~ /^pcf/;
+ next if $t =~ /^power/;
+ next if $t =~ /^Network: Infrastructure/;
+ next if $t =~ /^s3c2440-sdi/;
+ next if $t =~ /^mmc0:/;
+ next if $t =~ /^ar6000_wow/;
+ next if $t =~ /^BMI Get/;
+ next if $t =~ /^mapped channel/;
+ if ($t =~ /^Target debug interrupt/) {
+ print "STATE CRASH\n";
+ next;
+ }
+ if ($t !~ /^AR6000 /) {
+ die if $strict;
+ next;
+ }
+ $t = $';
+ next if $t =~ /^Reg/;
+ if ($t =~ /^disconnected/) {
+ print "STATE DISC\n";
+ next;
+ }
+ if ($t !~ /connected.*freq (\d+)/) {
+ die if $strict;
+ next;
+ }
+ $c = ($1-2412)/5+1;
+ if ($c == $cc) {
+ print "STATE ASSOC $c\n";
+ } elsif ($c == $pc) {
+ print "STATE LATE $c\n";
+ } else {
+ print "STATE WRONG $c\n";
+ }
+ next;
+ }
+
+ # special parsing states
+
+ if (defined $special) {
+ &special($l);
+ next;
+ }
+ if ($l =~ /^eth0\s+Scan completed/) {
+ *special = *scan;
+ undef $tmp;
+ next;
+ }
+ if ($l =~ /^PING/) {
+ *special = *ping;
+ undef $tmp;
+ next;
+ }
+
+ # synchronous notifications
+
+ if ($l =~ /^=== (.*) === (\d+)/) {
+ print "TIME $2\n";
+ $t = $1;
+ print "STATE $t\n";
+ if ($t =~ /RESET/) {
+ undef $pc;
+ $cc = 1;
+ next;
+ }
+ if ($t =~ /HOP (\d+) to (\d+)/) {
+ die if $cc != $1;
+ $pc = $1;
+ $cc = $2;
+ next;
+ }
+ next;
+ }
+#print "$l";
+}
Property changes on: developers/werner/wlan/freeze/r1.pl
___________________________________________________________________
Name: svn:executable
+ *
Added: developers/werner/wlan/freeze/r2.pl
===================================================================
--- developers/werner/wlan/freeze/r2.pl (rev 0)
+++ developers/werner/wlan/freeze/r2.pl 2009-01-22 02:49:42 UTC (rev 4893)
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+#
+# r2.pl - reductor #2
+#
+# This reductor takes a normalized session log and constructs the chains of
+# state transitions between visits to ROUND.
+#
+# The default output format omits all parameters so that one can easily do a
+# statistical analysis of the distinct chains.
+#
+
+$verbose = 0;
+$time = 0;
+
+while ($ARGV[0] =~ /^-/) {
+ if ($ARGV[0] eq "-v") {
+ shift(@ARGV);
+ $verbose = 1;
+ } elsif ($ARGV[0] eq "-t") {
+ shift(@ARGV);
+ $time = 1;
+ } else {
+ print STDERR "usage: $0 [-t] [-v]\n";
+ exit(1);
+ }
+}
+
+while (<>) {
+ $t = $1 if /^TIME (\d+)/;
+ next unless /^STATE/;
+ @s = split(/\s+/);
+ if ($s[1] eq "RESET") {
+ # if we enter RESET before HOP, this is in fact a problem that wasn't
+ # completely resolved in the previous round.
+ if ($last eq "ROUND") {
+ $out[$#out-1] .= " + RESET";
+ }
+ }
+ $last = $s[1];
+ if ($s[1] eq "ROUND") {
+ $out[$#out] = ($t-$t0)." ".$out[$#out] if $time && defined $t0;
+ $t0 = $t;
+ if ($verbose) {
+ $out[@out] = "#".$s[2];
+ } else {
+ $out[@out] = "ROUND";
+ }
+ } elsif ($s[1] eq "HOP") {
+ if ($verbose) {
+ $out[$#out] .= " -> HOP".$s[4];
+ } else {
+ $out[$#out] .= " -> HOP";
+ }
+ } else {
+ next unless @out;
+ $out[$#out] .= " -> $s[1]";
+ }
+
+}
+print join("\n", @out), "\n";
Property changes on: developers/werner/wlan/freeze/r2.pl
___________________________________________________________________
Name: svn:executable
+ *
Added: developers/werner/wlan/freeze/tst
===================================================================
--- developers/werner/wlan/freeze/tst (rev 0)
+++ developers/werner/wlan/freeze/tst 2009-01-22 02:49:42 UTC (rev 4893)
@@ -0,0 +1,155 @@
+#!/bin/bash
+
+#
+# tst - try to force a WLAN failure by changing the frequency of the access
+# point
+#
+
+# PING_IP is the addess we ping to check that we have a good WLAN connection
+# AP_IP is the address of the access point running OpenWRT
+# AP_PORT is the port we connect to
+# ESSID is the ESSID of the network we try to connect to
+# IWCONFIG is the configuration command we issue locally
+
+PING_IP=192.168.2.1
+AP_IP=192.168.0.200
+AP_PORT=2222
+ESSID=wgl
+IWCONFIG="key A4BEB3B8EC essid wgl"
+
+
+state()
+{
+ echo === "$@" === `date +"%s"`
+}
+
+
+channel()
+{
+ ssh -p $AP_PORT $AP_IP \
+ 'uci set wireless.wl0.channel='$1' && \
+ uci commit wireless && \
+ PATH=$PATH:/usr/sbin wifi'
+ chan=$1
+}
+
+
+hop()
+{
+ while true; do
+ c=`expr $RANDOM % 11 + 1`
+ [ $c != $chan ] && break
+ done
+ state HOP $chan to $c
+ channel $c
+}
+
+
+ping_n()
+{
+ ping -A -n -c $1 $PING_IP
+}
+
+
+ping_nt()
+{
+ ping -A -n -c $1 -w $2 $PING_IP
+}
+
+
+reset()
+{
+ state RESET
+ channel 1
+ echo s3c2440-sdi >/sys/bus/platform/drivers/s3c2440-sdi/unbind
+ echo s3c2440-sdi >/sys/bus/platform/drivers/s3c2440-sdi/bind
+ sleep 10
+ iwlist scan
+ iwconfig eth0 $IWCONFIG
+ dhclient eth0
+ ping_n 50
+}
+
+
+try_iwconfig()
+{
+ state IWCONFIG
+ iwconfig eth0 $IWCONFIG
+ if ping_nt 100 60; then
+ return
+ fi
+ iwlist scan
+ iwlist scan
+ iwlist scan
+ reset
+}
+
+
+try_iwscan()
+{
+ try=1
+ while [ $try -le 3 ]; do
+ state SCAN $try
+ i=$try
+ while [ $i -gt 0 ]; do
+ iwlist scan
+ i=`expr $i - 1`
+ done
+ if ping_nt 100 60; then
+ return
+ fi
+ try=`expr $try + 1`
+ done
+ reset
+}
+
+
+try_idle()
+{
+ tries=3
+ while [ $tries -gt 0 ]; do
+ s=`expr $RANDOM % 300`
+ state IDLE $s
+ sleep $s
+ if ping_nt 100 60; then
+ return
+ fi
+ tries=`expr $tries - 1`
+ done
+ iwlist scan
+ iwlist scan
+ iwlist scan
+ reset
+}
+
+
+round()
+{
+ state ROUND $n
+ if ! ping_nt 20 30; then
+ reset
+ return
+ fi
+ hop
+ if ping_nt 100 120; then
+ return
+ fi
+ state TROUBLE
+ case `expr $RANDOM % 3` in
+# case 1 in
+ 0) try_iwconfig;;
+ 1) try_iwscan;;
+ 2) try_idle;;
+ esac
+}
+
+
+# kill the default route
+route del default
+
+reset
+n=0
+while [ $n != ${1:-100} ]; do
+ n=`expr $n + 1`
+ round $n
+done
Property changes on: developers/werner/wlan/freeze/tst
___________________________________________________________________
Name: svn:executable
+ *
More information about the commitlog
mailing list