Please note: This project is no longer active. The website is kept online for historic purposes only.
If you´re looking for a Linux driver for your Atheros WLAN device, you should continue here .

UserDocs/Tools/GraphingIwconfig: graf_wlan.sh

File graf_wlan.sh, 18.8 kB (added by paolo, 13 years ago)

ASCII graphing iwconfig output - version 0.1.3

Line 
1 #!/bin/sh
2 #
3 # ASCII graphing madness of $IWCONFIG output
4 # (C) oopla <ten.fs.sresu@alpoo> - GPL<=2
5 # versions:
6 # 0.1   - initial release
7 # 0.1.1 - fixed sed regex ('Sensitivity')
8 # 0.1.2 - fixed missing init *_1 values; iwconfig path
9 #         added -d (debug) -s0 (alt regex) opts; fixed \3 <-> \4 order in subst
10 #         fixed missing -tp (for Tx-Power), -Mn (for MAXNL); fixed MAXLQ
11 #         changed -Ml -> -Ms, -ml -> -ms (MAX/MIN SL)
12 # 0.1.3 - fixed sed regexs for no ap, kBps, channel instead of freq, mW
13 #         added -pt -pr -pd: paths to antenna tx,rx,diversity flags
14 #         missing init val for TR; fixes for -ts; added -D opt
15 #         fixes for printing header
16 #
17 # needs bash(1) or any shell that's capable of doing $[ma*th] and ${s:ub:s}
18 # not too difficult to make it work in any POSIX minimal sh like (d)ash.
19 # sure ...
20 # - colorful would be cool(er) - yet slower
21 # - sticking header on top line w/ ncurses trick would be cool(er)
22 # - a C/C++ would be much faster and likely shorter
23 # - convert it in awk/perl/python/your-f-scr-lang
24 # - and, why not just hacking $IWCONFIG(8) to do the same natively, eh?
25 # your turn ;)
26 #
27 # If something breaks, check the sed(1) REGEX below against $IWCONFIG(8) output
28 #
29 AP="-"; SL=0; NL=0; SN=0; IFACE=; T=1; TX=0; RX=0; TR=0; PTA=; PRA=; PAD=
30 pIM=0; pIC=0; pIF=0; pIN=0; pTXR=0; pMB=0; CSV=0; pL=0
31 DELTA=0; pTP=0; pBR=0; pSL=0; pNL=0; pSN=0; pAP=0; pTX=0; pRX=0; pTS=0
32 LCSV=0; LSYS=0; LOGF=; ATS=0; HEADER=0; TSF=+%s
33 NFL=95; NL=$NFL; MAXSL=30; MINSL=85; SL=$NL; MAXBR=54; BR=0; MAXTP=20
34 MAXNL=75; MAXLQ=; LQ=0; N=10
35 MAXBRK=$[MAXBR*64]      #max tx/rx rate - top at half the link MAXBR, in kiBps
36 MAXTX=; MAXRX=
37 DIALC="-"; NDLC="+"
38 S=""; SI=""
39 TTY=${TTY:-`tty`}; r=$LINES; c=$COLUMNS
40 DEBUG=0; SED_RE=1
41 IWCONFIG=`which iwconfig`
42 [ "$IWCONFIG" ] || {
43   for p in /sbin /usr/sbin /usr/local/sbin;do
44     [ -x $p/iwconfig ] && IWCONFIG=$p/iwconfig && break
45   done
46 }
47 [ "$IWCONFIG" ] || {
48   echo "${0##*/}: unable to find iwconfig" >&2
49   exit 1
50 }
51
52 dialstr () {
53   i=1
54   S=""  # build our 'dial' string
55   Sx=""
56   while [ $i -lt $N ];do                # N slots + 1 needle = SW slots
57     S="$S$DIALC"
58     Sx="${Sx}_"
59     i=$[i+1]
60   done
61   # fix at 4 chars width of invalid*/missed beacon scales, incl. needle
62   SI="${DIALC}${DIALC}${DIALC}${DIALC}"
63   S2="${Sx:0:$[($N-1)/2]}"
64   S3="${Sx:$[($N-1)/2+1]}"
65 }
66
67 usage () {
68   echo "Usage: ${0##*/} options"
69   echo
70   echo "  Available options:"
71   grep '^[[:space:]]\+-[^ ]\+)' $0 | \
72      sed -e "s/) shift;[ ]*\([^ =]\+\)=.*#/ \1;/" -e "s/).*#/;/" |\
73   while read l;do
74     l1=${l%;*} l2=${l#*;}
75     l="printf \"    %-12s %-s\n\" \"$l1\" \"$l2\""
76     eval "$l"
77   done
78   dialstr
79   echo
80   printf "    dial:        |%s|\n" "${S:0:$[N/2]}$NDLC${S:$[N/2]}"
81   printf "                 |%s|\n" $SI
82   echo
83   exit 0
84 }
85
86 get_tty_rxc () {
87   if [ "$TTY" ]; then
88     if [ "$LINES" ] && [ "$COLUMNS" ]; then
89       r=$LINES
90       c=$COLUMNS
91     else
92       rc=`stty size`
93       r=${rc% *}
94       c=${rc#* }
95     fi
96   else
97     r=0; c=0
98   fi
99 }
100
101 # by default print just/at least ESSID and Link Quality
102 # print at least 10chars from ESSID, each graph is 10+2 chars wide
103 while [ "$1" ];do
104   case $1 in
105     -ap) pAP=1 ;;               #print AP MAC
106     -ts) shift; TSF=$1          #print timestamp (date "TSF" - default "$TSF")
107          pTS=1
108          case $1 in
109            +*) ;;
110            *) TSF=+%s ; continue ;;
111          esac
112          ;;
113     -D)  DELTA=1 ;;             #print iff output has changed (i.e. |uniq)
114     -br) pBR=1 ;;               #print bitrate
115     -sl) pSL=1 ;;               #print signal level
116     -nl) pNL=1 ;;               #print noise level
117     -sn) pSN=1 ;;               #print signal/noise ratio
118     -I) shift; IFACE=$1 ;;              #interface to watch
119     -i) shift; T=$1 ;;          #update interval (x.x s - default $T)
120     -tx) pTX=1 ;;               #print tx rate
121     -rx) pRX=1 ;;               #print rx rate
122     -tp) pTP=1 ;;               #print Tx-Power
123     -im) pIM=1 ;;               #print invalid misc (var)
124     -ic) pIC=1 ;;               #print invalid crypt (var)
125     -if) pIF=1 ;;               #print invalid frag (var)
126     -in) pIN=1 ;;               #print invalid nwid (var)
127     -te) pTXR=1 ;;              #print tx excess retry (var)
128     -pt) shift; PTA=$1 ;;       #path to tx antenna
129     -pr) shift; PRA=$1 ;;       #path to rx antenna
130     -pd) shift; PAD=$1 ;;       #path to diversity
131     -mb) pMB=1 ;;               #print missed beacons (var)
132     -nf) shift; NFL=$1 ;;       #set noise floor (-dBm - default $NFL)
133     -Ms) shift; MAXSL=$1 ;;     #set max signal  (-dBm - default $MAXSL)
134     -ms) shift; MINSL=$1 ;;     #set min signal  (-dBm - default $MINSL)
135     -Mn) shift; MAXNL=$1 ;;     #set max noise   (-dBm - default $MAXNL)
136     -Mb) shift; MAXBR=$1 ;;     #set max bitrate (Mibps - default $MAXBR)
137     -Mt) shift; MAXTX=$1 ;;     #set max Tx rate (kiBps - default $MAXBRK)
138     -Mr) shift; MAXRX=$1 ;;     #set max Rx rate (kiBps - default $MAXBRK)
139     -Mq) shift; MAXLQ=$1 ;;     #set max link quality (default $[NFL-$MAXSL])
140     -Mp) shift; MAXTP=$1 ;;     #set max Tx power (+dBm - default $MAXTP)
141     -nc) shift; NDLC=${1:0:1} ;;        #needle char (default '$NDLC')
142     -vc) shift; DIALC=${1:0:1} ;;       #dial chars (default '$DIALC')
143     -sw) shift; N=$1 ;;         #scale width in chars (default $N)
144     -wh) HEADER=1 ;;            #always have an header line within screen
145     -ls) LSYS=1 ;;              #log to syslog (as well)
146     -lf) shift; FLOG=$1 ;;      #log to named file
147     -cs) CSV=1 ;;               #output CSV data
148     -lc) LCSV=1 ;;              #log CSV data
149     -at) ATS=1 ;;               #adapt to terminal size
150     -d) DEBUG=1 ;;              #print some debugging on stderr
151     -s0) SED_RE=0 ;;            #select alternative sed(1) regex
152     *) usage ;;
153   esac
154   shift
155 done
156 [ "$IFACE" ] || {
157   echo "You must specify -I interface." >&2
158   exit 1
159 }
160 [ "$FLOG" ] && {
161   touch "$FLOG" || {
162     echo "${0##*/}: can't write to $FLOG" >&2
163     exit 1
164   }
165 }
166 ft=${T#*.}; t=${T%.*}   #decimals
167 t=${T%.*}; [ "$t" ] || t=0
168 # sleepenh(1) allows for fractional and <1s timing
169 SLEEP=sleepenh
170 hash sleepenh || {
171   SLEEP=sleep
172   [ $t = 0 ] && t=1
173   case "$ft" in [5-9]*) t=$[t+1] ;; *) ;; esac
174   ft=0
175   T=$t
176   echo "Note: sleepenh(1) not found - loop interval is $T s" >&2
177 }
178 dialstr
179 if [ $pTS = 1 ]; then
180   TS=`date "$TSF"`
181   CTSH="TimeStamp"
182   TSH="${CTSH}__________________"
183   if [ ${#TS} -lt ${#CTSH} ]
184   then l=${#CTSH}
185   else l=${#TS}
186   fi
187   TSH=${TSH:0:$l}
188   lTSH=$[1+${#TSH}]     #TSH+' '
189   clTSH=$[3+${#CTSH}]   #"+CTSH+"+,
190 else
191   lTSH=0
192   clTSH=0
193   TSH=""
194   CTSH=""
195 fi
196 [ "$PTA" ] && {
197   case "$PTA" in
198     /proc/*|/sys/*) ;;
199     *) [ -r "/proc/sys/$PTA" ] && PTA="/proc/sys/$PTA"
200        [ -r "/sys/$PTA" ] && PTA="/sys/$PTA"
201        [ -r "$PTA" ] || PTA=
202        ;;
203   esac
204 }
205 [ "$PRA" ] && {
206   case "$PRA" in
207     /proc/*|/sys/*) ;;
208     *) [ -r "/proc/sys/$PRA" ] && PRA="/proc/sys/$PRA"
209        [ -r "/sys/$PRA" ] && PRA="/sys/$PRA"
210        [ -r "$PRA" ] || PRA=
211        ;;
212   esac
213 }
214 [ "$PAD" ] && {
215   case "$PAD" in
216     /proc/*|/sys/*) ;;
217     *) [ -r "/proc/sys/$PAD" ] && PAD="/proc/sys/$PAD"
218        [ -r "/sys/$PAD" ] && PAD="/sys/$PAD"
219        [ -r "$PAD" ] || PAD=
220        ;;
221   esac
222 }
223 [ $HEADER = 1 ] && {
224       [ $CSV = 0 ] && {
225         [ $pTS = 1 ] && H="$TSH "     
226         H="${H}__ESSID___"
227         [ $pAP = 1 ] && H="$H _____AP(MAC)_____"
228         H="$H |${S2}LQ${S3}|"
229         [ $pBR = 1 ] && H="$H${S2}BR${S3}|"
230         [ $pSL = 1 ] && H="$H${S2}SL${S3}|"
231         [ $pNL = 1 ] && H="$H${S2}NL${S3}|"
232         [ $pTP = 1 ] && H="$H${S2}TP${S3}|"
233         [ $pSN = 1 ] && H="$H${S2}SN${S3}|"
234         [ $pTX = 1 ] && H="$H${S2}TX${S3}|"
235         [ $pRX = 1 ] && H="$H${S2}RX${S3}|"
236         [ "$PTA" ] || [ "$PRA" ] || [ "$PAD" ] && H="${H}TRD|"
237         [ $pMB = 1 ] && H="${H}_MB_|"
238         [ $pIN = 1 ] && H="${H}_IN_|"
239         [ $pIC = 1 ] && H="${H}_IC_|"
240         [ $pIM = 1 ] && H="${H}_IM_|"
241         [ $pIF = 1 ] && H="${H}_IF_|"
242         [ $pTXR = 1 ] && H="${H}_TR_|"
243       }
244       [ $CSV = 1 ] || [ $LCSV = 1 ] && {
245         [ $pTS = 1 ] && CH="\"$CTSH\","
246         CH="$CH\"ESSID\""
247         [ $pAP = 1 ] && CH="$CH,\"AP\""
248         CH="$CH,\"LQ\""
249         [ $pBR = 1 ] && CH="$CH,\"BR\""
250         [ $pSL = 1 ] && CH="$CH,\"SL\""
251         [ $pNL = 1 ] && CH="$CH,\"NL\""
252         [ $pTP = 1 ] && CH="$CH,\"TP\""
253         [ $pSN = 1 ] && CH="$CH,\"SN\""
254         [ $pTX = 1 ] && CH="$CH,\"TX\""
255         [ $pRX = 1 ] && CH="$CH,\"RX\""
256         [ "$PTA" ] || [ "$PRA" ] || [ "$PAD" ] && CH="$CH,\"ATRD\""
257         [ $pMB = 1 ] && CH="$CH,\"MB\""
258         [ $pIN = 1 ] && CH="$CH,\"IN\""
259         [ $pIC = 1 ] && CH="$CH,\"IC\""
260         [ $pIM = 1 ] && CH="$CH,\"IM\""
261         [ $pIF = 1 ] && CH="$CH,\"IF\""
262         [ $pTXR = 1 ] && CH="$CH,\"TXR\""
263       }
264 }
265 get_tty_rxc
266 MAXSN=$[NFL-$MAXSL]
267 MAXLQ=${MAXLQ:-$[NFL-$MAXSL]}
268 NR=$[NFL-$MAXNL]        #noise range for graph
269 SR=$[MINSL-$MAXSL]      #signal range for graph
270 MAXBRK=$[MAXBR*64]
271 MAXTX=${MAXTX:-$MAXBRK}; MAXRX=${MAXRX:-$MAXBRK}
272 [ $DEBUG = 1 ] && cat <<__F>&2
273 TTY=$TTY r,c=$r,$c T=$T t=$t ft=$ft t10=$[t*10+${ft:0:1}]
274 MAXSN=$MAXSN MAXLQ=$MAXLQ NR=$NR SR=$SR MAXBR=$MAXBR
275 MAXTX=$MAXTX MAXRX=$MAXRX MAXBRK=$MAXBRK
276 __F
277
278 # print header once at least
279 if [ $CSV = 0 ]; then
280   if [ $ATS = 1 ] && [ $c -gt 0 ];then
281     if [ ${#H} -gt $c ]
282     then echo "${H:0:$[c-1]}>"
283     else echo $H
284     fi
285   else
286     echo $H
287   fi
288 else
289   if [ $ATS = 1 ] && [ $c -gt 0 ];then
290     if [ ${#CH} -gt $c ]
291     then echo "${CH:0:$[c-1]}>"
292     else echo $CH
293     fi
294   else
295     echo $CH
296   fi
297 fi
298 i=1
299 [ $LSYS = 1 ] && \
300   #drop our timestamp anyway as logger(1) already does it
301   if [ $LCSV = 0 ]
302   then logger -t iwconf.$IFACE "${H:$lTSH}"
303   else logger -t iwconf.$IFACE "${CH:$clTSH}"
304   fi
305 [ "$FLOG" ] && \
306   if [ $LCSV = 0 ]
307   then echo "$H" > "$FLOG"
308   else echo "$CH" > "$FLOG"
309   fi
310
311 while true;do
312   # choose your method; either try to grab subexpressions (default) or
313   # try to delete everything but the wanted values (opt -s0)
314   # Hope Jean won't change these labels in $IWCONFIG(8)
315   if [ $SED_RE = 1 ]; then
316     # need LANG=C to avoid locale msgs
317     IWC=`LANG=C $IWCONFIG $IFACE | tr '\n' ' '`
318     set -- `echo $IWC |\
319       sed  -n "s/.\+ESSID[=:]\"\?\([^\"]*\)\".\+\(Frequency\|Channel\)[=:][ ]*\([.0-9]*\).\+Access Point[:=][ ]*\([^ ]*\).\+Bit Rate[=:][ ]*\([0-9]*\).\+Tx-Power[:=][ ]*\([-+.0-9]*\).\+Link Quality[:=][ ]*\([0-9]*\).\+Signal level[:=][- ]*\([0-9]*\).\+Noise level[:=][- ]*\([0-9]*\).\+/\"\1\" \3 \4 \5 \6 \7 \8 \9/p"`
320     [ $DEBUG = 1 ] && echo -n "sed_re=$SED_RE: $@" >&2
321     ESSID=${1%\"}; ESSID=${ESSID#\"}
322     FREQ=$2
323     AP=$3
324     BR=$4
325     TXP=$5
326     LQ=$6
327     SL=$7
328     NL=$8
329     # grab&print next bunch of replacements
330     set -- `echo $IWC |\
331       sed -n "s/.*Rx invalid nwid[=:][ ]*\([0-9]*\)[ ]\+Rx invalid crypt[=:][ ]*\([0-9]*\)[ ]\+Rx invalid frag[=:][ ]*\([0-9]*\)[ ]\+Tx excessive retries[=:][ ]*\([0-9]*\)[ ]\+Invalid misc[=:][ ]*\([0-9]*\)[ ]\+Missed beacon[=:][ ]*\([0-9]*\).*/\1 \2 \3 \4 \5 \6/p"`
332     [ $DEBUG = 1 ] && echo $@ >&2
333     IN=$1
334     IC=$2
335     IF=$3
336     TXER=$4
337     IM=$5
338     MB=$6
339   else
340     # do all at once by subctraction
341     set -- `LANG=C $IWCONFIG $IFACE | tr '\n' ' '|\
342       sed -e s/.*ESSID[=:]// \
343         -e "s/[ ]*Mode[:=].*Frequency[:=][ ]*/ /" \
344         -e "s/ \(GHz\)\?[ ]*Access Point[:=][ ]*/ /" \
345         -e "s/[ ]*Bit Rate[:=][ ]*/ /" \
346         -e "s, [kM]b/s[ ]*Tx-Power[:=][ ]*, ," \
347         -e "s/ \(mW\|dBm\)[ ]*\(Sens.*\)\?.*Link Quality[:=][ ]*/ /" \
348         -e "s/[ ]*Signal level[:=][- ]*/ /" \
349         -e "s/ dBm[ ]*Noise level[:=][- ]*/ /" \
350         -e "s/ dBm[ ]*Rx invalid nwid[:=][ ]*/ /" \
351         -e "s/[ ]*Rx invalid crypt[:=][ ]*/ /" \
352         -e "s/[ ]*Rx invalid frag[:=][ ]*/ /" \
353         -e "s/[ ]*Tx excessive retries[:=][ ]*/ /" \
354         -e "s/[ ]*Invalid misc[:=][ ]*/ /" \
355         -e "s/[ ]*Missed beacon[:=][ ]*/ /"`
356     [ $DEBUG = 1 ] && echo "sed_re=$SED_RE: $@" >&2
357     ESSID=${1%\"}; ESSID=${ESSID#\"}
358     FREQ=$2
359     AP=$3
360     BR=$4
361     TXP=$5
362     LQ=$6
363     SL=$7
364     NL=$8
365     IN=$9
366     IC=${10}
367     IF=${11}
368     TXER=${12}
369     IM=${13}
370     MB=${14}
371   fi
372   LQ=${LQ%/*}
373   [ $ATS = 1 ] && get_tty_rxc
374   [ $HEADER = 1 ] && [ "$TTY" ] && [ $r -gt 0 ] && {
375     [ $i = 0 ] && {
376       if [ $CSV = 0 ]; then
377         if [ $ATS = 1 ] && [ $c -gt 0 ];then
378           if [ ${#H} -gt $c ]
379           then echo "${H:0:$[c-1]}>"
380           else echo $H
381           fi
382         else
383          echo $H
384         fi
385       else
386         if [ $ATS = 1 ] && [ $c -gt 0 ];then
387           if [ ${#CH} -gt $c ]
388           then echo "${CH:0:$[c-1]}>"
389           else echo $CH
390           fi
391         else
392           echo $CH
393         fi
394       fi
395     }
396     [ $DELTA = 0 ] || [ $pL = 1 ] || [ $i = 0 ] && i=$[($i+1)%$[r-2]]
397     pL=0
398   }
399   [ $pTX = 1 ] || [ $pRX = 1 ] && {
400     #set -- `grep $IFACE: /proc/net/dev|cut -d: -f2`
401     #this in 1000 cycles loop is ~8 times faster on my pc ...
402     while read l;do
403       case $l in
404         $IFACE:*) l=${l#*:}; set $l; break ;;
405         *) ;;
406       esac
407     done < /proc/net/dev
408     RX=$1
409     TX=$9
410     [ "$TX_1" ] || TX_1=$TX
411     [ "$RX_1" ] || RX_1=$RX
412     if [ $t = $ft ]; then
413       # time interval has no decimals
414       tx=$[($TX-$TX_1)/$t/1024] # in kiBps
415       rx=$[($RX-$RX_1)/$t/1024] # in kiBps
416     else
417       # 1st decimal pos is enough
418       t10=$[t*10+${ft:0:1}]
419       tx=$[($TX-$TX_1)*10/$t10/1024] # in kiBps
420       rx=$[($RX-$RX_1)*10/$t10/1024] # in kiBps
421     fi
422     #or just use bc(1) instead of above mess:
423     #tx=`echo "tx=($TX-$TX_1)/$T; scale=0; print tx/1024"|bc -l`
424     #rx=`echo "rx=($RX-$RX_1)/$T; scale=0; print rx/1024"|bc -l`
425     TX_1=$TX
426     RX_1=$RX
427   }
428   L=""; CL=""
429   [ "$PTA" ] || [ "$PRA" ] || [ "$PAD" ] && {
430     if [ "$PTA" ]
431     then ta=`cat $PTA`; ta=${ta:0:1}
432     else ta=x
433     fi
434     if [ "$PRA" ]
435     then ra=`cat $PRA`; ra=${ra:0:1}
436     else ra=x
437     fi
438     if [ "$PAD" ]
439     then ad=`cat $PAD`; ad=${ad:0:1}
440     else ad=x
441     fi
442   }
443   if [ $CSV = 1 ] || [ $LCSV = 1 ]; then
444     [ $pTS = 1 ] && L="\"`date "$TSF"`\","
445     CL="$L\"$ESSID\""
446     [ $pAP = 1 ] && CL="$CL,\"$AP\""
447     CL="$CL,\"$LQ\""
448     [ $pBR = 1 ] && CL="$CL,\"$BR\""
449     [ $pSL = 1 ] && CL="$CL,\"$SL\""
450     [ $pNL = 1 ] && CL="$CL,\"$NL\""
451     [ $pTP = 1 ] && CL="$CL,\"$TXP\""
452     [ $pSN = 1 ] && CL="$CL,\"$SN\""
453     [ $pTX = 1 ] && CL="$CL,\"$tx\""
454     [ $pRX = 1 ] && CL="$CL,\"$rx\""
455     [ "$PTA" ] || [ "$PRA" ] || [ "$PAD" ] && CL="$CL,\"$ta$ra$ad\""
456     [ $pMB = 1 ] && CL="$CL,\"$MB\""
457     [ $pIN = 1 ] && CL="$CL,\"$IN\""
458     [ $pIC = 1 ] && CL="$CL,\"$IC\""
459     [ $pIM = 1 ] && CL="$CL,\"$IM\""
460     [ $pIF = 1 ] && CL="$CL,\"$IF\""
461     [ $pTXR = 1 ] && CL="$CL,\"$TR\""
462   else
463     [ $pTS = 1 ] && {
464       TS=`date "$TSF"`
465       TS="$TS          "
466       L="${TS:0:${#TSH}} "
467     }
468     essid="$ESSID                "; essid="${essid:0:10}"
469     L="$L$essid"
470     [ $pAP = 1 ] && {
471       AP="$AP                 "; AP=${AP:0:17}
472       L="$L $AP"
473     }
474     lq=$LQ; [ $lq -gt $MAXLQ ] && lq=$MAXLQ
475     L="$L |${S:0:$[lq*$N/$MAXLQ]}+${S:$[lq*$N/$MAXLQ]}|"
476     [ $pBR = 1 ] && {
477       br=$BR; [ $br -gt $MAXBR ] && br=$MAXBR
478       L="$L${S:0:$[br*$N/$MAXBR]}+${S:$[br*$N/$MAXBR]}|"
479     }
480     [ $pSL = 1 ] && {
481       sl=$[MINSL-$SL]; [ $sl -lt 0 ] && sl=0
482       L="$L${S:0:$[sl*$N/$SR]}+${S:$[sl*$N/$SR]}|"
483     }
484     [ $pNL = 1 ] && {
485       nl=$[NL-$MAXNL]; [ $nl -lt 0 ] && nl=0
486       L="$L${S:$[nl*$N/$NR]}+${S:0:$[nl*$N/$NR]}|"
487     }
488     [ $pTP = 1 ] && {
489       tp=$TXP; [ $tp -gt $MAXTP ] && tp=$MAXTP
490       L="$L${S:0:$[tp*$N/$MAXTP]}+${S:$[tp*$N/$MAXTP]}|"
491     }
492     #LQ should bear same info, but that's driver/card dependent
493     [ $pSN = 1 ] && {
494       sn=$[NL-$SL]; [ $sn -lt 0 ] && sn=0
495       L="$L${S:0:$[sn*$N/$MAXSN]}+${S:$[sn*$N/$MAXSN]}|"
496     }
497     [ $pTX = 1 ] && {
498       [ $tx -gt $MAXTX ] && tx=$MAXTX
499       L="$L${S:0:$[tx*$N/$MAXTX]}+${S:$[tx*$N/$MAXTX]}|"
500     }
501     [ $pRX = 1 ] && {
502       [ $rx -gt $MAXRX ] && rx=$MAXRX
503       L="$L${S:0:$[rx*$N/$MAXRX]}+${S:$[rx*$N/$MAXRX]}|"
504     }
505     [ "$PTA" ] || [ "$PRA" ] || [ "$PAD" ] && L="$L$ta$ra$ad|"
506     [ $pMB = 1 ] && {
507       [ "$MB_1" ] || MB_1=$MB
508       if [ $MB = 0 ] || [ $MB = $MB_1 ]; then
509         L="$L${SI:0}|"
510       else
511         dMB=$[MB-$MB_1]
512         if [ $dMB -gt $[t*4] ]  ; then L="$L${SI:0:3}+|"
513         elif [ $dMB -gt $[t*3] ]; then L="$L${SI:0:2}+${SI:3}|"
514         elif [ $dMB -gt $[t*2] ]; then L="$L${SI:0:1}+${SI:2}|"
515         else L="$L+${SI:1}|"
516         fi
517       fi
518       MB_1=$MB
519     }
520     [ $pIN = 1 ] && {
521       [ "$IN_1" ] || IN_1=$IN
522       if [ $IN = 0 ] || [ $IN = $IN_1 ]; then
523         L="$L${SI:0}|"
524       else
525         dIN=$[IN-$IN_1]
526         if [ $dIN -gt $[t*4] ]  ; then L="$L${SI:0:3}+|"
527         elif [ $dIN -gt $[t*3] ]; then L="$L${SI:0:2}+${SI:3}|"
528         elif [ $dIN -gt $[t*2] ]; then L="$L${SI:0:1}+${SI:2}|"
529         else L="$L+${SI:1}|"
530         fi
531       fi
532       IN_1=$IN
533     }
534     [ $pIC = 1 ] && {
535       [ "$IC_1" ] || IC_1=$IC
536       if [ $IC = 0 ] || [ $IC = $IC_1 ]; then
537         L="$L${SI:0}|"
538       else
539         dIC=$[IC-$IC_1]
540         if [ $dIC -gt $[t*4] ]  ; then L="$L${SI:0:3}+|"
541         elif [ $dIC -gt $[t*3] ]; then L="$L${SI:0:2}+${SI:3}|"
542         elif [ $dIC -gt $[t*2] ]; then L="$L${SI:0:1}+${SI:2}|"
543         else L="$L+${SI:1}|"
544         fi
545       fi
546       IC_1=$IC
547     }
548     [ $pIM = 1 ] && {
549       [ "$IM_1" ] || IM_1=$IM
550       if [ $IM = 0 ] || [ $IM = $IM_1 ]; then
551         L="$L${SI:0}|"
552       else
553         dIM=$[IM-$IM_1]
554         if [ $dIM -gt $[t*4] ]  ; then L="$L${SI:0:3}+|"
555         elif [ $dIM -gt $[t*3] ]; then L="$L${SI:0:2}+${SI:3}|"
556         elif [ $dIM -gt $[t*2] ]; then L="$L${SI:0:1}+${SI:2}|"
557         else L="$L+${SI:1}|"
558         fi
559       fi
560       IM_1=$IM
561     }
562     [ $pIF = 1 ] && {
563       [ "$IF_1" ] || IF_1=$IF
564       if [ $IF = 0 ] || [ $IF = $IF_1 ]; then
565         L="$L${SI:0}|"
566       else
567         dIF=$[IF-$IF_1]
568         if [ $dIF -gt $[t*4] ]  ; then L="$L${SI:0:3}+|"
569         elif [ $dIF -gt $[t*3] ]; then L="$L${SI:0:2}+${SI:3}|"
570         elif [ $dIF -gt $[t*2] ]; then L="$L${SI:0:1}+${SI:2}|"
571         else L="$L+${SI:1}|"
572         fi
573       fi
574       IN_1=$IN
575     }
576     [ $pTXR = 1 ] && {
577       [ "$TR_1" ] || TR_1=$TR
578       if [ $TR = 0 ] || [ $TR = $TR_1 ]; then
579         L="$L${SI:0}|"
580       else
581         dTR=$[TR-$TR_1]
582         if [ $dTR -gt $[t*4] ]  ; then L="$L${SI:0:3}+|"
583         elif [ $dTR -gt $[t*3] ]; then L="$L${SI:0:2}+${SI:3}|"
584         elif [ $dTR -gt $[t*2] ]; then L="$L${SI:0:1}+${SI:2}|"
585         else L="$L+${SI:1}|"
586         fi
587       fi
588       TR_1=$TR
589     }
590   fi
591   if [ $CSV = 0 ]; then
592     [ $DELTA = 0 ] || [ "${_L:$lTSH}" != "${L:$lTSH}" ] && {
593       if [ $ATS = 1 ] && [ $c -gt 0 ]; then
594         if [ ${#L} -gt $c ]
595         then echo "${L:0:$[c-1]}>"
596         else echo "$L"
597         fi
598       else
599         echo "$L"
600       fi
601       pL=1
602     }
603   else
604     [ $DELTA = 0 ] || [ "${_CL:$clTSH}" != "${CL:$clTSH}" ] && {
605       if [ $ATS = 1 ] && [ $c -gt 0 ]; then
606         if [ ${#CL} -gt $c ]
607         then echo "${CL:0:$[c-1]}>"
608         else echo "$CL"
609         fi
610       else
611         echo "$CL"
612       fi
613       pL=1
614     }
615   fi
616   [ $LSYS = 1 ] && {
617     #drop our timestamp anyway as logger(1) already does it
618     if [ $LCSV = 0 ]; then
619       [ $DELTA = 0 ] || [ "${_L:$lTSH}" != "${L:$lTSH}" ] && \
620       logger -t iwconf.$IFACE "${L:$lTSH}"
621     else
622       [ $DELTA = 0 ] || [ "${_CL:$clTSH}" != "${CL:$clTSH}" ] && \
623       logger -t iwconf.$IFACE "${CL:$clTSH}"
624     fi
625   }
626   [ "$FLOG" ] && {
627     if [ $LCSV = 0 ]; then
628       [ $DELTA = 0 ] || [ "${_L:$lTSH}" != "${L:$lTSH}" ] && \
629       echo "$L" >> "$FLOG"
630     else
631       [ $DELTA = 0 ] || [ "${_CL:$clTSH}" != "${CL:$clTSH}" ] && \
632       echo "$CL" >> "$FLOG"
633     fi
634   }
635   _L=$L
636   _CL=$CL
637   $SLEEP $T &>/dev/null
638 done
639