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