#! /usr/bin/perl # # use GD; use POSIX; $FONT=gdSmallFont; $fontsize{gdSmallFont}=4; $fontsize{gdGiantFont}=10; $MIN_QUALITY=-150; $xsize=800;$ysize=600; $step=0; srand(0); $xm=90100; $xM=97970; $ym=461050; $yM=466800; $neato='/usr/bin/neato'; init (); while ($step < 10) { print "\n\nStep: $step\n"; local($fn)=sprintf("output/why_%04d.log",$step); open (WHY,">$fn") || die "Could not create: $fn\n"; # $node=$nodes[rand($#NODES)]; foreach $node #('CNodeJasper') (@NODES) #('CNodeEvert') { # print "Doing: $node\n"; optimize_node($node); } calc_routes(); rate(); output(); close(WHY); } sub rate() { $diacount=$dia=$disc=0; foreach $node (@NODES) { local($connections)=0; foreach $other_node (@NODES) { if ($node eq $other_node) {next;} $hops=$HOPS{$node}{$other_node}; if ($hops >= 0) { # print "$node->$other_node = $hops : $connections\n"; $connections++; $dia+=$hops;$diacount++; } } if ($connections eq 0) {$disc++;print "DISCONNECTED: $node = $HOPS{$node}{CNodeCope}\n";} } $dia=sprintf("%.3f",$dia/$diacount); } sub calc_routes { %ROUTE=();%HOPS=();%NO_ROUTE=(); print "Calculating routes...\n"; foreach $node (@NODES) { if (! @{$PTP{$node}}) {next;} foreach $other_node (@NODES) { if (! @{$PTP{$other_node}}) {next;} #print "TR $node => $other_node\n"; $route=calc_route($node,$other_node,$node,0); #print "ROUTE $node => $other_node = $ROUTE{$node}{$other_node}\n"; } } } sub calc_route { local($node,$other_node,$path,$depth)=@_; local($result)=0; local($hops,$on); if ($HOPS{$node}{$other_node} < 0) {return(-1);} # print $depth . " " x $depth . "$path => $other_node\n"; if ($node eq $other_node) { #print "DONE: $depth:$path\n\n"; $ROUTE{$node}{$other_node}="$node";$HOPS{$node}{$other_node}=0; return(0); } if (grep(/$other_node/,@{$PTP{$node}})) { # print "DIRECT LINK: " . join(':',grep(/$other_node/,@{$PTP{$node}})) . "\n"; $ROUTE{$node}{$other_node}="$node|$other_node";$HOPS{$node}{$other_node}=1; return(1); } if (! add_route($path)) {return(-1);} if (exists($HOPS{$node}{$other_node})) {return($HOPS{$node}{$other_node});} foreach $on (@{$PTP{$node}}) { if ($path=~/$on/) {next;} if ($ROUTE{$node}{$other_node}=~/$on/) {next;} $hops=calc_route($on,$other_node,"$path|$on",$depth+1); if ($hops >= 0) { #print "RETURN: $node->$other_node=$hops\n"; add_route("$node|$ROUTE{$on}{$other_node}"); if ($hops eq 1) {last;} } elsif ($hops < 0) {last;} #else {print "RETURNED=$hops.\n";} } if (($HOPS{$node}{$other_node} eq '') && ($depth eq 0)) {$HOPS{$node}{$other_node}=-1;} #print "NOROUTE: $node -> $other_node\n";} return($HOPS{$node}{$other_node}); } sub add_route { local($path)=@_; local(@route)=split(/\|/,$path); local($hops)=$#route; local($node)=shift(@route); local($other_node)=pop(@route); if ($HOPS{$node}{$other_node} >0 ) { if ($HOPS{$node}{$other_node} < $hops) {return(0);} if ($HOPS{$node}{$other_node} eq $hops) {return(1);} } $ROUTE{$node}{$other_node}=$path; $HOPS{$node}{$other_node}=$hops; #print "KORTER: ($HOPS{$node}{$other_node}) $node->$other_node=$ROUTE{$node}{$other_node}\n"; return(1); if ($ROUTE{$other_node}{$node} eq '') { add_route(join('|',reverse(split(/\|/,$path)))); } } sub optimize_node { local($node)=@_; local($other_node); local($connected_to)=''; foreach $if (keys %{$MASTER{$node}}) { if (! $MASTER{$node}{$if}) {optimize_if($node,$if);} } foreach $other_node (@NODES) { if ($LNAME{$node} eq $LNAME{$other_node}) { push(@{$PTP{$node}},$other_node); push(@{$PTP{$other_node}},$node); } } } sub optimize_if { local($node,$if)=@_; # print "OptIf: $node:$if:$MASTER{$node}{$if}\n"; local(@fns)=sort(glob("measurements/$node/*.$if")); local(%scores)=(); # print "FNS: " . join (':',@fns) . "\n"; $fn=pop(@fns); if ($fn ne '') { #print "FN: $fn\n"; open(MEAS,$fn) || die "Could not open $fn\n"; while() { #print $_; chomp(); if (/^(\S+)\((\d+)x\):\s+(\d+)\s+(\d+)\s+(\d+)\s+\[(\d+)\]/) { $essid=$1;$count=$2;$S=$3;$N=$4;$SNR=$5;$channel=$6; # $essid=~s/renv/rv/i; # $essid=~s/martenso/marten/i; #print "TEST:$essid:$count:$S\n"; } elsif (/^\s+(\d+)\s+(\S+):\s+(\d+)\s+(\d+)\s+(\d+)\s+\[(\d+)\]/) { $essid=$2;$count=$1;$S=$3;$N=$4;$SNR=$5;$channel=$6; } else {next;} if ($essid=~/\.wleiden.net/) { $other_node=$ESSID2NODE{$essid}; if ($node eq $other_node) {next;} if (($other_node!~/$LNAME{$node}/i) && ((($S > 0)) || ($count >30))) { if ($S>0) {$q=$S;} else {$q=$count-200;} print WHY "$node->$other_node = $q ($essid)\n"; $ON=$ESSID2NODE{$essid}; $scores{$essid}=score($node,$if,$ON,$q); } } } close(MEAS); @choises=sort {$scores{$a} <=> $scores{$b}} keys %scores; if ($best=pop(@choises)) { print WHY "BEST: $best ($scores{$best})\n"; if ($LINK{$node}{$if}!~/$best/) { $LINK{$node}{$if}=$other_node=$ESSID2NODE{$best}; push(@{$PTP{$node}},$other_node); push(@{$PTP{$other_node}},$node); $connected_to.="$other_node:"; #print "NEW:$LINK{$node}{$if}\n" ; } #else {print "Nothing changed.\n";} } } } sub score { local($node,$if,$other_node,$q)=@_; local($score)=$q; print WHY "$node:$if ($q:$connected_to) ~ $other_node "; if ($connected_to=~/$other_node/i) {$score=-200;} elsif ($q > $MIN_QUALITY) { if ($ROUTE{$node}{$other_node} eq '') {$score+=200;#if ($step > 1) {print "CONNECTED: $node - $other_node\n";} } foreach $on (@NODES) { $myhops=$HOPS{$node}{$other_node}; $onhops=$HOPS{$on}{$other_node}; $diff=$myhops-($onhops+1); if (($myhops eq '') && ($onhops ne '')) {$score+=200;} #print "REPAIR: $node -- $other_node via $on\n";} elsif ($diff > 3) {$score+=$diff; } } } print WHY "SCORE: $score\n"; return($score); } sub output { local($w) = new GD::Image(799,601,); $w = $n->clone; colors(); print "Output: $step\n"; local($dotfn)=sprintf("output/area_%04d.dot",$step); open (DOT,">$dotfn") || die "Could not create: $dotfn\n"; print DOT <copy($bludot,$x,$y,0,0,10,10); # $x+=2+2*$fontsize{$FONT};$y-=$fontsize{$FONT}/3; $x+=10; $w->string($FONT,$x,$y,$NAME{$node},$COLOR{black}); $snode=$LNAME{$node}; if (! exists($DOTDONE{$snode})) { printf DOT "\n\"%s\"[fontsize=20,label=\"%s\",color=\"%s\",pos=\"%f,%f\"]\n", lc($snode),$snode,"#0000FF",$ox{$node},$oy{$node}; $DOTDONE{$snode}=1; } } print DOT "\n\n"; foreach $node (@NODES) { foreach $if (keys %{$LINK{$node}}) { $other_node=$LINK{$node}{$if}; if ($other_node ne '') { local($ox)=$x{$other_node}; local($oy)=$y{$other_node}; local($x)=$x{$node}; local($y)=$y{$node}; #print "$node,$other_node=$x,$y,$ox,$oy\n"; $cx=($x%256); $cy=($y%256); $color= $w->colorAllocate($cx,$cy,256-($cx+$cy)/2); $w->line($x,$y,$ox,$oy,$color); local($dx)=$ox-$x; local($dy)=$oy-$y; local($angle)=atan2($dy,$dx);$dx=$x+($dx/3);$dy=$y+($dy/3); local($a1)=$angle+.17; local($a2)=$angle-.17; local($l)=25; $y=$l*sin($a1);$x=$l*cos($a1); $w->line($dx-$x,$dy-$y,$dx,$dy,$color); $y1=$l*sin($a2);$x1=$l*cos($a2); $w->line($dx-$x1,$dy-$y1,$dx,$dy,$color); if (($x{$node} eq '') ||($y{$node} eq '')) {print "ZEROn: $node=$x{$node},$y{$node}\n";} if (($x{$other_node} eq '') ||($y{$other_node} eq '')) {print "ZEROo($node): $other_node=$x{$other_node},$y{$other_node}\n";} $sslave=$LNAME{$node}; $smaster=$LNAME{$other_node}; $style='bold';# "dashed", "dotted", "solid", "invis" and "bold" $len=5; $port=''; $routes=count_routes($node,$other_node); printf "% 3d:ROUTES $node - $other_node step: $step\n",$routes; $R=240-($routes/ 150)*240; $lcolor=sprintf("#%02x%02x%02x",$R,$R,$R); printf DOT " \"%s\" -> \"%s\" [style=%s,len=%d,color=\"$lcolor\"${port},headlabel=\"$routes\"]\n", lc($sslave),lc($smaster),$style,$len,$lcolor; } } } $w->string(gdSmallFont,600,580,"Step: $step Dia: $dia Disc: $disc",$COLOR{blue}); local($fn)=sprintf("output/mesh_%04d.png",$step); open (FN,">$fn") || die "Could not create: $fn\n"; binmode FN; print FN $w->png; close FN; print DOT "\n}\n"; close(DOT); local($jpgfn)=sprintf("output/mesh_%04d.jpg",$step); if ($DEBUG) {print "Doing neato.\n";} system ("/bin/bash -c 'ulimit -t 30; $neato -Tjpg -o $jpgfn $dotfn'"); $step++; } sub count_routes { local($node,$other_node)=@_; local($counter)=0; foreach $n1 (keys %ROUTE) { foreach $n2 (keys %{$ROUTE{$n1}}) { $route=$ROUTE{$n1}{$n2}; if ($route=~/\S+\|($node\|$other_node)|($other_node\|$node)\|\S+/) { $counter++; #print "INR: $node-$other_node: $route\n"; } } } return($counter); } sub tan { sin($_[0]) / cos($_[0]) } sub init { open(NODES,"nodes") || die; while () { chomp(); if (s/^([^=]+)=(\d+),(\d+)//) { $node=$1;$X=$2;$Y=$3; if ($node=~/CNodeHMgw2|CNodeHM|CNodeHenk|CNodeMLK|CNodeKaag2|CNodeRene/) {next;} push(@NODES,$node); # print "$node=>$X,$Y\n"; $ox{$node}=$X;$oy{$node}=$Y; if (($X < $xm) || ($X > $xM) || ($Y < $ym) || ($Y > $yM)) { if (($X > 0) && ($Y>0)) { $counter=0; print "LIMIT: $node ($X,$Y) ->"; if ($X > $xM) {$X=$xM-(($counter %10)*400);} elsif ($X < $xm) {$X=$xm+-(($counter %10)*400);} if ($Y > $yM) {$Y=$yM-int($counter/10)*400;} elsif ($Y < $ym) {$Y=$ym+int($counter/10)*400;} print "($X,$Y)\n"; } else { # $txt.="$name"; $x=$xM-(($counter %10)*400); $y=$ym+int($counter/10)*400; } $counter++; } $x=floor(.5+($X-90000)/10); $y=floor(.5+(467000-$Y)/10)-12; $x{$node}=$x;$y{$node}=$y; $name=lc($node);$name=~s/^.node//;$NAME{$node}=$name; $name=~s/\d+//;$name=~s/unigorn/unigor/;$name=~s/martensoe/marten/; $LNAME{$node}=$name; foreach $i (split(/\|/)) { if ($i ne '') { if ($i=~/(\S+)([=:])(\S+)/) { $if=$1; $master=$2; $essid=$3; $ESSID{$node}{$if}=$essid; if ($master eq '=') {$MASTER{$node}{$if}=1;$ESSID2NODE{$essid}=$node;} else {$MASTER{$node}{$if}=0;} } } } } } close(NODES); $fn='leiden4.png'; #$n = new GD::Image($fn) || die "Could not open file: $fn\n"; $n = new GD::Image($xsize,$ysize); $n->colorAllocate(255,255,255); $reddot=GD::Image->new("reddot10.png"); $bludot=GD::Image->new("bludot10.png"); } sub colors { $COLOR{white} = $w->colorAllocate(255,255,255); $COLOR{gray} = $w->colorAllocate(150,150,150); $COLOR{black} = $w->colorAllocate(0,0,0); $COLOR{blue} = $w->colorAllocate(0,0,255); $C[$c++]=$COLOR{green} = $w->colorAllocate(0,255,0); $C[$c++]=$COLOR{darkgreen} = $w->colorAllocate(0,155,0); $C[$c++]=$COLOR{orange} = $w->colorAllocate(255,110,0); $C[$c++]=$COLOR{blue} = $w->colorAllocate(0,0,255); $C[$c++]=$COLOR{red} = $w->colorAllocate(255,0,0); $C[$c++]=$COLOR{brown} = $w->colorAllocate(139,69,19); $C[$c++]=$COLOR{margenta}= $w->colorAllocate(255,0,255); $C[$c++]=$COLOR{cyan} = $w->colorAllocate(0,150,255); $C[$c++]=$COLOR{cyan4} = $w->colorAllocate(0,139,139); $C[$c++]=$COLOR{dorchid} = $w->colorAllocate(153,50,204); }