Nel lungo periodo del passaggio tra Telecom e Tiscali sono stato senza connettività adsl e in questo periodo ho “usufruito” di connettività wireless a scrocco.
Da casa mia si prendevano varie stazioni wireless ma solo alcune (due) erano effettivamente abbastanza potenti da permettere una connessione abbastanza stabile e non lo erano per tutto il giorno. Mi sono reso conto che la semplice stima “qualità del segnale” che si può ottenere con “iwlist s” sotto linux non è per nulla indicativa in quanto non tiene conto della costanza del segnale e non permette quindi di poter stabilire a priori quale stazione vale la pena di provare (provare con uno script che tenta di connettersi a oltranza…non provare a mano)
Allora ho deciso di applicare gli insegnamenti di una delle poche materie universitarie che mi ha insegnato qualcosa in maniera utile: ho usato la media esponenziale ponderata per stimare il tempo medio di ricezione dei beacon.
La media esponenziale ponderata è descritta nell’RFC2988 ed è tipicamente usata per stimare l’RTT nelle connessioni TCP; essa può essere facilmente adattata alla stima dell’intervallo tra la ricezione dei beacon perchè i due “scenari” (nel senso americano del termine) sono molto simili.
A differenza della media aritmetica ,che assegna un peso contante ai singoli campioni, la media esponenziale ponderata assegna un peso che decresce esponenzialmente dall’ultimo campione; in questo modo i campioni recenti hanno un peso superiore rispetto ai campioni vecchi.
per calcolare la media esponenziale ponderata si fa uso di 4 variabili:A,B,MEDIA,CAMPIONE
MEDIA è il valore attuale della media
CAMPIONE è il valore dell’ultimo rilevamento
A e B sono i pesi da dare all’ultimo campione e ai campioni precedenti; tipicamente A+B=1
inizialmente MEDIA è posto uguale a CAMPIONE. il suo valore viene aggiornato secondo la formula:
questo è lo script:
#!/usr/bin/ruby @alpha=1.0/8 @n=0 @beacon=0 @power=0 @delay=2 @oldpower=0 def battery() responso=[] `cat /proc/acpi/battery/BAT1/state`.each{|riga| responso<<riga} attuale=responso[4].scan(/:.*/).to_s[7..-1].to_f massima=responso[3].scan(/:.*/).to_s[7..-1].to_f percento=(100*attuale/massima).to_i return "Batteria in carica: #{attuale}mAh" if not responso[2].scan("discharging").size>0 return "Nella batteria rimangono "+responso[4].scan(/:.*/).to_s[7..-1]+" pari al #{percento}%" end def monitor(essid) while(true) responso= `iwlist eth1 s` celle=tokenize(responso) ora=Time.now.strftime("%I:%M:%S ") puts "\ec \n#{ora} #{battery()}\n"+celle[essid] # beacon=celle[essid].scan(/beacon.*/).to_s[8..-7].to_i power=celle[essid].scan(/uality.*/).to_s[7..-6].to_i statistiche(power,beacon) puts "\n",celle.keys.inspect puts "Q per uscire" sleep(@delay) end end def statistiche(power,beacon) same=(power-@oldpower).abs if(@n==0 || @power+@beacon==0) @beacon=beacon @power=power else #medie esponenziali ponderate (RFC2988) @beacon=(1-3*@alpha)*@beacon+3*@alpha*beacon if power>0 @power=(1-@alpha)*@power+@alpha*power @power=4*@alpha*@power if power==0 @beacon=@beacon+ 1000*@delay if (beacon==0 && power==0 && @beacon<10**6 && @beacon>0) end @oldpower=power puts "Power = #{power}" puts "Latence = #{beacon}\n" puts "Scarto = #{same.to_i}%\n" verso="up";verso="down" if @power>power puts "MPower = #{@power} (#{verso})"; verso="up";verso="down" if @beacon>beacon puts "MLatence = #{@beacon} (#{verso})" @n=@n+1 end def tokenize(stream) token=Hash.new("None") stream.each("Cell"){|cella| nome=cella.scan(/ESSID.*/).to_s[7...-1] token[nome]=cella } return token end print "Inserire L'essid da monitorare ";essid=readline.chomp #monitor(essid) esecutore=Thread.new {monitor(essid)} while(cosa=readline.chomp.upcase) if cosa=="Q" then Thread.kill(esecutore) exit end end
4 comments
1 ping
Vai al modulo dei commenti ↓
theblackvoice
12 novembre 2008 a 23:34 (UTC 2) Link a questo commento
Perché non lo pacchettizzi per diverse versioni?
E’ uno strumento semplice ma efficace, lo userebbero in molti imho
thedarshan
13 novembre 2008 a 11:43 (UTC 2) Link a questo commento
Beh…fare un pacchetto per un singolo file?
casomai metto un link diretto per scaricarlo.
per quanto riguarda la storia delle versioni…l’unica parte che nn funziona su tutti i kernel è il monitoraggio della batteria, e francamente non saprei come verificarne la compatibilità
theblackvoice
18 novembre 2008 a 16:55 (UTC 2) Link a questo commento
Se la smettessi di scrivere in ruby forse qualcuno lo proverebbe pure, il codice XD
thedarshan
18 novembre 2008 a 18:37 (UTC 2) Link a questo commento
E in cosa dovrei scrivere? in C++?
é un parser! o lo scrivo in ruby o lo scrivo in perl.
e comunque visto che lo script parte solo per linux e ormai ruby è preinstallato in tutte le distribuzioni…
Stimare accuratamente la potenza di una wireless (parte due) « The Darshan’s Weblog
21 novembre 2008 a 16:10 (UTC 2) Link a questo commento
[...] la potenza di una wireless (parte due) Ho fatto una modifica allo script del post precedente facendo in modo che lo script controlli tutte le wireless [...]