lantiq: get more status information from xDSL
[openwrt/openwrt.git] / target / linux / lantiq / base-files / lib / functions / lantiq_dsl.sh
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2012-2014 OpenWrt.org
3
4 if [ "$( which vdsl_cpe_control )" ]; then
5 XDSL_CTRL=vdsl_cpe_control
6 else
7 XDSL_CTRL=dsl_cpe_control
8 fi
9
10 #
11 # Basic functions to send CLI commands to the vdsl_cpe_control daemon
12 #
13 dsl_cmd() {
14 killall -0 ${XDSL_CTRL} && (
15 echo "$@" > /tmp/pipe/dsl_cpe0_cmd
16 cat /tmp/pipe/dsl_cpe0_ack
17 )
18 }
19 dsl_val() {
20 echo $(expr "$1" : '.*'$2'=\([-\.[:alnum:]]*\).*')
21 }
22 dsl_string() {
23 echo $(expr "$1" : '.*'$2'=(\([A-Z0-9,]*\))')
24 }
25
26 #
27 # Simple divide by 10 routine to cope with one decimal place
28 #
29 dbt() {
30 local a=$(expr $1 / 10)
31 local b=$(expr $1 % 10)
32 echo "${a}.${b}"
33 }
34 #
35 # Take a number and convert to k or meg
36 #
37 scale() {
38 local val=$1
39 local a
40 local b
41
42 if [ "$val" -gt 1000000 ]; then
43 a=$(expr $val / 1000)
44 b=$(expr $a % 1000)
45 a=$(expr $a / 1000)
46 printf "%d.%03d Mb" ${a} ${b}
47 elif [ "$val" -gt 1000 ]; then
48 a=$(expr $val / 1000)
49 printf "%d Kb" ${a}
50 else
51 echo "${val} b"
52 fi
53 }
54
55 scale_latency() {
56 local val=$1
57 local a
58 local b
59
60 a=$(expr $val / 100)
61 b=$(expr $val % 100)
62 printf "%d.%d ms" ${a} ${b}
63 }
64
65 #
66 # Read the data rates for both directions
67 #
68 data_rates() {
69 local csg
70 local dru
71 local drd
72 local sdru
73 local sdrd
74
75 csg=$(dsl_cmd g997csg 0 1)
76 drd=$(dsl_val "$csg" ActualDataRate)
77
78 csg=$(dsl_cmd g997csg 0 0)
79 dru=$(dsl_val "$csg" ActualDataRate)
80
81 [ -z "$drd" ] && drd=0
82 [ -z "$dru" ] && dru=0
83
84 sdrd=$(scale $drd)
85 sdru=$(scale $dru)
86
87 if [ "$action" = "lucistat" ]; then
88 echo "dsl.data_rate_down=$drd"
89 echo "dsl.data_rate_up=$dru"
90 echo "dsl.data_rate_down_s=\"$sdrd\""
91 echo "dsl.data_rate_up_s=\"$sdru\""
92 else
93 echo "Data Rate: Down: ${sdrd}/s / Up: ${sdru}/s"
94 fi
95 }
96
97 #
98 # Chipset
99 #
100 chipset() {
101 local vig
102 local cs
103 local csv
104
105 vig=$(dsl_cmd vig)
106 cs=$(dsl_val "$vig" DSL_ChipSetType)
107 csv=$(dsl_val "$vig" DSL_ChipSetHWVersion)
108 csfw=$(dsl_val "$vig" DSL_ChipSetFWVersion)
109 csapi=$(dsl_val "$vig" DSL_DriverVersionApi)
110
111 if [ "$action" = "lucistat" ]; then
112 echo "dsl.chipset=\"${cs} ${csv}\""
113 echo "dsl.firmware_version=\"${csfw}\""
114 echo "dsl.api_version=\"${csapi}\""
115 else
116 echo "Chipset: ${cs} ${csv}"
117 echo "Firmware Version: ${csfw}"
118 echo "API Version: ${csapi}"
119 fi
120 }
121
122 #
123 # Vendor information
124 #
125 vendor() {
126 local lig
127 local vid
128 local svid
129
130 lig=$(dsl_cmd g997lig 1)
131 vid=$(dsl_string "$lig" G994VendorID)
132 svid=$(dsl_string "$lig" SystemVendorID)
133
134 if [ "$action" = "lucistat" ]; then
135 echo "dsl.atuc_vendor_id=\"${vid}\""
136 echo "dsl.atuc_system_vendor_id=\"${svid}\""
137 else
138 echo "ATU-C Vendor ID: ${vid}"
139 echo "ATU-C System Vendor ID: ${svid}"
140 fi
141 }
142
143 #
144 # XTSE capabilities
145 #
146 xtse() {
147 local xtusesg
148 local xtse1
149 local xtse2
150 local xtse3
151 local xtse4
152 local xtse5
153 local xtse6
154 local xtse7
155 local xtse8
156
157 local xtse_s=""
158
159 local annex_s=""
160 local line_mode_s=""
161 local cmd=""
162
163 xtusesg=$(dsl_cmd g997xtusesg)
164 xtse1=$(dsl_val "$xtusesg" XTSE1)
165 xtse2=$(dsl_val "$xtusesg" XTSE2)
166 xtse3=$(dsl_val "$xtusesg" XTSE3)
167 xtse4=$(dsl_val "$xtusesg" XTSE4)
168 xtse5=$(dsl_val "$xtusesg" XTSE5)
169 xtse6=$(dsl_val "$xtusesg" XTSE6)
170 xtse7=$(dsl_val "$xtusesg" XTSE7)
171 xtse8=$(dsl_val "$xtusesg" XTSE8)
172
173 # Evaluate Annex (according to G.997.1, 7.3.1.1.1)
174 if [ $((xtse1 & 13)) != 0 \
175 -o $((xtse2 & 1)) != 0 \
176 -o $((xtse3 & 12)) != 0 \
177 -o $((xtse4 & 3)) != 0 \
178 -o $((xtse6 & 3)) != 0 \
179 -o $((xtse8 & 1)) != 0 ]; then
180 annex_s=" A,"
181 fi
182
183 if [ $((xtse1 & 48)) != 0 \
184 -o $((xtse2 & 2)) != 0 \
185 -o $((xtse3 & 48)) != 0 \
186 -o $((xtse6 & 12)) != 0 \
187 -o $((xtse8 & 2)) != 0 ]; then
188 annex_s="$annex_s B,"
189 fi
190
191 if [ $((xtse1 & 194)) != 0 \
192 -o $((xtse2 & 12)) != 0 \
193 -o $((xtse8 & 4)) != 0 ]; then
194 annex_s="$annex_s C,"
195 fi
196
197 if [ $((xtse4 & 48)) != 0 \
198 -o $((xtse5 & 3)) != 0 \
199 -o $((xtse6 & 192)) != 0 ]; then
200 annex_s="$annex_s I,"
201 fi
202
203 if [ $((xtse4 & 192)) != 0 \
204 -o $((xtse7 & 3)) != 0 ]; then
205 annex_s="$annex_s J,"
206 fi
207
208 if [ $((xtse5 & 60)) != 0 ]; then
209 annex_s="$annex_s L,"
210 fi
211
212 if [ $((xtse5 & 192)) != 0 \
213 -o $((xtse7 & 12)) != 0 ]; then
214 annex_s="$annex_s M,"
215 fi
216
217 annex_s=`echo ${annex_s:1}`
218 annex_s=`echo ${annex_s%?}`
219
220 # Evaluate Line Mode (according to G.997.1, 7.3.1.1.1)
221
222 # Regional standard: ANSI T1.413
223 if [ $((xtse1 & 1)) != 0 ]; then
224 line_mode_s=" T1.413,"
225 fi
226
227 # Regional standard: TS 101 388
228 if [ $((xtse1 & 1)) != 0 ]; then
229 line_mode_s="$line_mode_s TS 101 388,"
230 fi
231
232 if [ $((xtse1 & 252)) != 0 ]; then
233 line_mode_s="$line_mode_s G.992.1 (ADSL),"
234 fi
235
236 if [ $((xtse2 & 15)) != 0 ]; then
237 line_mode_s="$line_mode_s G.992.2 (ADSL lite),"
238 fi
239
240 if [ $((xtse3 & 60)) != 0 \
241 -o $((xtse4 & 240)) != 0 \
242 -o $((xtse5 & 252)) != 0 ]; then
243 line_mode_s="$line_mode_s G.992.3 (ADSL2),"
244 fi
245
246 if [ $((xtse4 & 3)) != 0 \
247 -o $((xtse5 & 3)) != 0 ]; then
248 line_mode_s="$line_mode_s G.992.4 (ADSL2 lite),"
249 fi
250
251 if [ $((xtse6 & 199)) != 0 \
252 -o $((xtse7 & 15)) != 0 ]; then
253 line_mode_s="$line_mode_s G.992.5 (ADSL2+),"
254 fi
255
256 if [ $((xtse8 & 7)) != 0 ]; then
257 line_mode_s="$line_mode_s G.993.2 (VDSL2),"
258 fi
259
260 #!!! PROPRIETARY & INTERMEDIATE USE !!!
261 if [ $((xtse8 & 128)) != 0 ]; then
262 line_mode_s="$line_mode_s G.993.1 (VDSL),"
263 fi
264
265 line_mode_s=`echo ${line_mode_s:1}`
266 line_mode_s=`echo ${line_mode_s%?}`
267
268 xtse_s="${xtse1}, ${xtse2}, ${xtse3}, ${xtse4}, ${xtse5}, ${xtse6}, ${xtse7}, ${xtse8}"
269
270 if [ "$action" = "lucistat" ]; then
271 echo "dsl.xtse1=$xtse1"
272 echo "dsl.xtse2=$xtse2"
273 echo "dsl.xtse3=$xtse3"
274 echo "dsl.xtse4=$xtse4"
275 echo "dsl.xtse5=$xtse5"
276 echo "dsl.xtse6=$xtse6"
277 echo "dsl.xtse7=$xtse7"
278 echo "dsl.xtse8=$xtse8"
279 echo "dsl.xtse_s=\"$xtse_s\""
280 echo "dsl.annex_s=\"${annex_s}\""
281 echo "dsl.line_mode_s=\"${line_mode_s}\""
282 else
283 echo "XTSE Capabilities: ${xtse_s}"
284 echo "Annex: ${annex_s}"
285 echo "Line Mode: ${line_mode_s}"
286 fi
287 }
288
289 #
290 # Power Management Mode
291 #
292 power_mode() {
293 local pmsg=$(dsl_cmd g997pmsg)
294 local pm=$(dsl_val "$pmsg" nPowerManagementStatus);
295 local s;
296
297 case "$pm" in
298 "-1") s="Power management state is not available" ;;
299 "0") s="L0 - Synchronized" ;;
300 "1") s="L1 - Power Down Data transmission (G.992.2)" ;;
301 "2") s="L2 - Power Down Data transmission (G.992.3 and G.992.4)" ;;
302 "3") s="L3 - No power" ;;
303 *) s="unknown" ;;
304 esac
305
306 if [ "$action" = "lucistat" ]; then
307 echo "dsl.power_mode_num=$pm"
308 echo "dsl.power_mode_s=\"$s\""
309 else
310 echo "Power Management Mode: $s"
311 fi
312 }
313
314 #
315 # Latency type (interleave delay)
316 #
317 latency_delay() {
318 local csg
319
320 local idu
321 local idu_s;
322 local sidu
323
324 local idd
325 local idd_s;
326 local sidd
327
328 csg=$(dsl_cmd g997csg 0 1)
329 idd=$(dsl_val "$csg" ActualInterleaveDelay)
330
331 csg=$(dsl_cmd g997csg 0 0)
332 idu=$(dsl_val "$csg" ActualInterleaveDelay)
333
334 [ -z "$idd" ] && idd=0
335 [ -z "$idu" ] && idu=0
336
337 if [ "$idd" > 100 ]; then
338 idd_s="Interleave"
339 else
340 idd_s="Fast"
341 fi
342
343 if [ "$idu" > 100 ]; then
344 idu_s="Interleave"
345 else
346 idu_s="Fast"
347 fi
348
349 sidu=$(scale_latency $idu)
350 sidd=$(scale_latency $idd)
351
352 if [ "$action" = "lucistat" ]; then
353 echo "dsl.latency_num_down=\"$sidu\""
354 echo "dsl.latency_num_up=\"$sidd\""
355 echo "dsl.latency_s_down=\"$idd_s\""
356 echo "dsl.latency_s_up=\"$idu_s\""
357 else
358 echo "Latency / Interleave Delay: Down: ${idd_s} (${sidd}) / Up: ${idu_s} (${sidu})"
359 fi
360 }
361
362 #
363 # Errors
364 #
365 errors() {
366 local lsctg
367 local dpctg
368 local ccsg
369 local esf
370 local esn
371 local sesf
372 local sesn
373 local lossf
374 local lossn
375 local uasf
376 local uasn
377
378 local crc_pf
379 local crc_pn
380 local crcp_pf
381 local crcp_pn
382 local hecf
383 local hecn
384
385 local fecn
386 local fecf
387
388 lsctg=$(dsl_cmd pmlsctg 1)
389 esf=$(dsl_val "$lsctg" nES)
390 sesf=$(dsl_val "$lsctg" nSES)
391 lossf=$(dsl_val "$lsctg" nLOSS)
392 uasf=$(dsl_val "$lsctg" nUAS)
393
394 lsctg=$(dsl_cmd pmlsctg 0)
395 esn=$(dsl_val "$lsctg" nES)
396 sesn=$(dsl_val "$lsctg" nSES)
397 lossn=$(dsl_val "$lsctg" nLOSS)
398 uasn=$(dsl_val "$lsctg" nUAS)
399
400 dpctg=$(dsl_cmd pmdpctg 0 1)
401 hecf=$(dsl_val "$dpctg" nHEC)
402 crc_pf=$(dsl_val "$dpctg" nCRC_P)
403 crcp_pf=$(dsl_val "$dpctg" nCRCP_P)
404
405 dpctg=$(dsl_cmd pmdpctg 0 0)
406 hecn=$(dsl_val "$dpctg" nHEC)
407 crc_pn=$(dsl_val "$dpctg" nCRC_P)
408 crcp_pn=$(dsl_val "$dpctg" nCRCP_P)
409
410 ccsg=$(dsl_cmd pmccsg 0 1 0)
411 fecf=$(dsl_val "$ccsg" nFEC)
412
413 ccsg=$(dsl_cmd pmccsg 0 0 0)
414 fecn=$(dsl_val "$ccsg" nFEC)
415
416 if [ "$action" = "lucistat" ]; then
417 echo "dsl.errors_fec_near=$fecn"
418 echo "dsl.errors_fec_far=$fecf"
419 echo "dsl.errors_es_near=$esn"
420 echo "dsl.errors_es_far=$esf"
421 echo "dsl.errors_ses_near=$sesn"
422 echo "dsl.errors_ses_far=$sesf"
423 echo "dsl.errors_loss_near=$lossn"
424 echo "dsl.errors_loss_far=$lossf"
425 echo "dsl.errors_uas_near=$uasn"
426 echo "dsl.errors_uas_far=$uasf"
427 echo "dsl.errors_hec_near=$hecn"
428 echo "dsl.errors_hec_far=$hecf"
429 echo "dsl.errors_crc_p_near=$crc_pn"
430 echo "dsl.errors_crc_p_far=$crc_pf"
431 echo "dsl.errors_crcp_p_near=$crcp_pn"
432 echo "dsl.errors_crcp_p_far=$crcp_pf"
433 else
434 echo "Forward Error Correction Seconds (FECS): Near: ${fecn} / Far: ${fecf}"
435 echo "Errored seconds (ES): Near: ${esn} / Far: ${esf}"
436 echo "Severely Errored Seconds (SES): Near: ${sesn} / Far: ${sesf}"
437 echo "Loss of Signal Seconds (LOSS): Near: ${lossn} / Far: ${lossf}"
438 echo "Unavailable Seconds (UAS): Near: ${uasn} / Far: ${uasf}"
439 echo "Header Error Code Errors (HEC): Near: ${hecn} / Far: ${hecf}"
440 echo "Non Pre-emtive CRC errors (CRC_P): Near: ${crcp_pn} / Far: ${crcp_pf}"
441 echo "Pre-emtive CRC errors (CRCP_P): Near: ${crcp_pn} / Far: ${crcp_pf}"
442 fi
443 }
444
445 #
446 # Work out how long the line has been up
447 #
448 line_uptime() {
449 local ccsg
450 local et
451 local etr
452 local d
453 local h
454 local m
455 local s
456 local rc=""
457
458 ccsg=$(dsl_cmd pmccsg 0 0 0)
459 et=$(dsl_val "$ccsg" nElapsedTime)
460
461 [ -z "$et" ] && et=0
462
463 d=$(expr $et / 86400)
464 etr=$(expr $et % 86400)
465 h=$(expr $etr / 3600)
466 etr=$(expr $etr % 3600)
467 m=$(expr $etr / 60)
468 s=$(expr $etr % 60)
469
470
471 [ "${d}${h}${m}${s}" -ne 0 ] && rc="${s}s"
472 [ "${d}${h}${m}" -ne 0 ] && rc="${m}m ${rc}"
473 [ "${d}${h}" -ne 0 ] && rc="${h}h ${rc}"
474 [ "${d}" -ne 0 ] && rc="${d}d ${rc}"
475
476 [ -z "$rc" ] && rc="down"
477
478
479 if [ "$action" = "lucistat" ]; then
480 echo "dsl.line_uptime=${et}"
481 echo "dsl.line_uptime_s=\"${rc}\""
482 else
483
484 echo "Line Uptime Seconds: ${et}"
485 echo "Line Uptime: ${rc}"
486 fi
487 }
488
489 #
490 # Get noise and attenuation figures
491 #
492 line_data() {
493 local lsg
494 local latnu
495 local latnd
496 local satnu
497 local satnd
498 local snru
499 local snrd
500 local attndru
501 local attndrd
502 local sattndru
503 local sattndrd
504 local actatpu
505 local actatpd
506
507 lsg=$(dsl_cmd g997lsg 1 1)
508 latnd=$(dsl_val "$lsg" LATN)
509 satnd=$(dsl_val "$lsg" SATN)
510 snrd=$(dsl_val "$lsg" SNR)
511 attndrd=$(dsl_val "$lsg" ATTNDR)
512 actatpd=$(dsl_val "$lsg" ACTATP)
513
514 lsg=$(dsl_cmd g997lsg 0 1)
515 latnu=$(dsl_val "$lsg" LATN)
516 satnu=$(dsl_val "$lsg" SATN)
517 snru=$(dsl_val "$lsg" SNR)
518 attndru=$(dsl_val "$lsg" ATTNDR)
519 actatpu=$(dsl_val "$lsg" ACTATP)
520
521 [ -z "$latnd" ] && latnd=0
522 [ -z "$latnu" ] && latnu=0
523 [ -z "$satnd" ] && satnd=0
524 [ -z "$satnu" ] && satnu=0
525 [ -z "$snrd" ] && snrd=0
526 [ -z "$snru" ] && snru=0
527
528 latnd=$(dbt $latnd)
529 latnu=$(dbt $latnu)
530 satnd=$(dbt $satnd)
531 satnu=$(dbt $satnu)
532 snrd=$(dbt $snrd)
533 snru=$(dbt $snru)
534 actatpd=$(dbt $actatpd)
535 actatpu=$(dbt $actatpu)
536
537 [ -z "$attndrd" ] && attndrd=0
538 [ -z "$attndru" ] && attndru=0
539
540 sattndrd=$(scale $attndrd)
541 sattndru=$(scale $attndru)
542
543 if [ "$action" = "lucistat" ]; then
544 echo "dsl.line_attenuation_down=$latnd"
545 echo "dsl.line_attenuation_up=$latnu"
546 echo "dsl.noise_margin_down=$snrd"
547 echo "dsl.noise_margin_up=$snru"
548 echo "dsl.signal_attenuation_down=$satnd"
549 echo "dsl.signal_attenuation_up=$satnu"
550 echo "dsl.actatp_down=$actatpd"
551 echo "dsl.actatp_up=$actatpu"
552 echo "dsl.max_data_rate_down=$attndrd"
553 echo "dsl.max_data_rate_up=$attndru"
554 echo "dsl.max_data_rate_down_s=\"$sattndrd\""
555 echo "dsl.max_data_rate_up_s=\"$sattndru\""
556 else
557 echo "Line Attenuation (LATN): Down: ${latnd}dB / Up: ${latnu}dB"
558 echo "Signal Attenuation (SATN): Down: ${satnd}dB / Up: ${satnu}dB"
559 echo "Noise Margin (SNR): Down: ${snrd}dB / Up: ${snru}dB"
560 echo "Aggregate Transmit Power(ACTATP): Down: ${actatpd}dB / Up: ${actatpu}dB"
561 echo "Max. Attainable Data Rate (ATTNDR): Down: ${sattndrd}/s / Up: ${sattndru}/s"
562 fi
563 }
564
565 #
566 # Is the line up? Or what state is it in?
567 #
568 line_state() {
569 local lsg=$(dsl_cmd lsg)
570 local ls=$(dsl_val "$lsg" nLineState);
571 local s;
572
573 case "$ls" in
574 "0x0") s="not initialized" ;;
575 "0x1") s="exception" ;;
576 "0x10") s="not updated" ;;
577 "0xff") s="idle request" ;;
578 "0x100") s="idle" ;;
579 "0x1ff") s="silent request" ;;
580 "0x200") s="silent" ;;
581 "0x300") s="handshake" ;;
582 "0x380") s="full_init" ;;
583 "0x400") s="discovery" ;;
584 "0x500") s="training" ;;
585 "0x600") s="analysis" ;;
586 "0x700") s="exchange" ;;
587 "0x800") s="showtime_no_sync" ;;
588 "0x801") s="showtime_tc_sync" ;;
589 "0x900") s="fastretrain" ;;
590 "0xa00") s="lowpower_l2" ;;
591 "0xb00") s="loopdiagnostic active" ;;
592 "0xb10") s="loopdiagnostic data exchange" ;;
593 "0xb20") s="loopdiagnostic data request" ;;
594 "0xc00") s="loopdiagnostic complete" ;;
595 "0x1000000") s="test" ;;
596 "0xd00") s="resync" ;;
597 "0x3c0") s="short init entry" ;;
598 "") s="not running daemon"; ls="0xfff" ;;
599 *) s="unknown" ;;
600 esac
601
602 if [ "$action" = "lucistat" ]; then
603 echo "dsl.line_state_num=$ls"
604 echo "dsl.line_state_detail=\"$s\""
605 if [ "$ls" = "0x801" ]; then
606 echo "dsl.line_state=\"UP\""
607 else
608 echo "dsl.line_state=\"DOWN\""
609 fi
610 else
611 if [ "$ls" = "0x801" ]; then
612 echo "Line State: UP [$ls: $s]"
613 else
614 echo "Line State: DOWN [$ls: $s]"
615 fi
616 fi
617 }
618
619 status() {
620 vendor
621 chipset
622 xtse
623 line_state
624 errors
625 power_mode
626 latency_delay
627 data_rates
628 line_data
629 line_uptime
630 }
631
632 lucistat() {
633 echo "local dsl={}"
634 status
635 echo "return dsl"
636 }