#!/bin/sh # B6L passive observation of a failed registration: NO writes to the modem (QMI GETs + AT read queries only), no radio/mode change. # AT port opened ONCE for the whole observation (proven safe pattern; rapid open/close crashed JZ02 MPSS). Stops early when # registered + PS attached (scenario A, one extra sample recorded) or MSS leaves 'running'. O=${1:-/tmp/l-obs}; DUR=${2:-900}; P=${3:-15}; mkdir -p $O/raw; Q="qmicli -p -d /dev/wwan0qmi0"; AT=/dev/wwan0at0 B=/sys/bus/platform/devices/4080000.remoteproc:bam-dmux; RPS=/sys/class/remoteproc/remoteproc0/state up() { cut -d' ' -f1 /proc/uptime; } v() { grep -m1 -oE "$1: *'[^']*'" $2 2>/dev/null | sed -E "s/.*'([^']*)'/\1/"; } lte() { sed -n '/LTE service:/,/SIM reject/p' $1; } atl() { grep -E "< \\$1:" $O/at.txt | tail -1 | sed -E 's/.*< //; s/\r//'; } D0=$(dmesg | wc -l); T0=$(up) printf 't_rel\tuptime\tss_reg\tss_ps\tss_plmn\tss_status\tss_forbidden\tsi_status\tsi_true\tsi_domain\tsi_plmn\tsi_eci\tsi_tac\tcl_plmn\tcl_tac\tcl_eci\tcl_earfcn\tcl_pci\tsig_rsrp\tsig_rsrq\tsig_snr\tat_cereg\tat_cgreg\tat_creg\tat_cgatt\tat_cops\tmss\tbam\tdmesg_err\tusb\temmc_w\n' > $O/timeline.tsv echo "[$(up)] open $AT" > $O/at.txt; exec 3<>$AT ( while IFS= read -r l <&3; do echo "[$(up)] < $l"; done ) >> $O/at.txt 2>&1 & RP=$!; echo "<5>[l-obs] begin dur=$DUR period=$P" > /dev/kmsg n=0; RES=B; extra=0 while :; do ts=$(up); n=$((n+1)); R=$O/raw/$n; mkdir -p $R for a in nas-get-serving-system nas-get-system-info nas-get-signal-info nas-get-cell-location-info; do timeout 20 $Q --$a > $R/$a.txt 2>&1; done for c in AT+CEREG? AT+CGREG? AT+CREG? AT+CGATT? AT+COPS?; do echo "[$(up)] > $c (sample $n)" >> $O/at.txt; printf '%s\r' "$c" >&3; sleep 1; done SS=$R/nas-get-serving-system.txt; SI=$R/si-lte.txt; lte $R/nas-get-system-info.txt > $SI; CL=$R/nas-get-cell-location-info.txt; SG=$R/nas-get-signal-info.txt SP=$(sed -n '/Current PLMN/,/Description/p' $SS | grep -oE "M[CN]C: '[^']*'" | sed -E "s/.*'([^']*)'/\1/" | tr '\n' '-' | sed 's/-$//') E=$(dmesg | tail -n +$((D0+1)) | grep -cE 'Failed to resume|-110|EAGAIN|Resource temporarily|crash detected|fatal error|[Ww]atchdog|wdog|Oops|BUG:|remoteproc.*(fail|error)') U=$(ping -c1 -W2 172.16.42.2 >/dev/null 2>&1 && echo ok || echo FAIL) printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ $(awk -v a=$ts -v b=$T0 'BEGIN{printf "%.0f", a-b}') $ts "$(v 'Registration state' $SS)" "$(v PS $SS)" "$SP" "$(v Status $SS)" "$(v Forbidden $SS)" \ "$(v Status $SI)" "$(v 'True Status' $SI)" "$(v Domain $SI)" "$(v MCC $SI)-$(v MNC $SI)" "$(v 'Cell ID' $SI)" "$(v 'Tracking Area Code' $SI)" \ "$(v PLMN $CL)" "$(v 'Tracking Area Code' $CL)" "$(v 'Global Cell ID' $CL)" "$(v 'EUTRA Absolute RF Channel Number' $CL)" "$(v 'Serving Cell ID' $CL)" \ "$(v RSRP $SG)" "$(v RSRQ $SG)" "$(v SNR $SG)" "$(atl +CEREG)" "$(atl +CGREG)" "$(atl +CREG)" "$(atl +CGATT)" "$(atl +COPS)" \ "$(cat $RPS)" "$(cat $B/power/runtime_status)" $E $U "$(awk '{print $5"/"$7}' /sys/block/mmcblk0/stat)" >> $O/timeline.tsv [ "$(cat $RPS)" = running ] || { RES=MSS-$(cat $RPS); break; } [ $extra = 1 ] && break grep -q "Registration state: 'registered'" $SS && grep -q "PS: 'attached'" $SS && { RES=A-registered; extra=1; echo "<5>[l-obs] registered+attached at sample $n" > /dev/kmsg; } [ $extra = 1 ] && { sleep $P; continue; } [ "$(awk -v a=$(up) -v b=$T0 -v d=$DUR 'BEGIN{print (a-b>=d)}')" = 1 ] && break w=$(awk -v a=$(up) -v b=$ts -v p=$P 'BEGIN{d=p-(a-b); printf "%.1f", (d>0)?d:0}'); sleep $w done sleep 1; kill $RP 2>/dev/null; exec 3>&-; echo "[$(up)] closed $AT" >> $O/at.txt; tr -d '\r' < $O/at.txt > $O/at.clean.txt echo "RESULT=$RES samples=$n dur=$(awk -v a=$(up) -v b=$T0 'BEGIN{printf "%.0f", a-b}')s" > $O/result.txt echo "<5>[l-obs] end $(cat $O/result.txt)" > /dev/kmsg; cat $O/result.txt