ims-pdn-up: a profile list without the ims APN is not final before the modem is registered
The profile-list query answered while ModemManager is still enabling the modem can be partial: entries, but no ims yet. The lookup took that as "no ims profile", fell back to the APN-string request — the one a walled carrier refuses — and never looked again (dev phone cold boot 2026-09-24 18:18:59: "none for apn ims" at `enabling`, the ims profile listed when read minutes later (18:19–18:25); harmless on KPN, a refused boot on O2 UK). The 0.3.8 fix covered only an empty list. Treat a list without the APN as final only when the modem is registered (or already connecting/connected); before that, retry it after the registration wait like a failed lookup. A retry that still has no final answer logs the modem state. Tested on the dev phone (KPN) in builds of this series; not every path has run there.
This commit is contained in:
parent
db848c6490
commit
f8fd5a3aa8
1 changed files with 27 additions and 10 deletions
|
|
@ -65,34 +65,49 @@ log "modem $MODEM"
|
||||||
# lookup itself can fail while ModemManager is still enabling the modem; a
|
# lookup itself can fail while ModemManager is still enabling the modem; a
|
||||||
# failed lookup is not "no profile" (the APN-string request it would fall
|
# failed lookup is not "no profile" (the APN-string request it would fall
|
||||||
# back to is the one the modem refuses under an IPv4 attach), so it is
|
# back to is the one the modem refuses under an IPv4 attach), so it is
|
||||||
# retried after the registration wait and only a list without the APN
|
# retried after the registration wait; a list without the APN is final —
|
||||||
# falls back to the APN string.
|
# the APN string is used — only once the modem is registered.
|
||||||
LOOKUP=pending
|
LOOKUP=pending
|
||||||
if [ -n "$PROFILE_ID" ]; then
|
if [ -n "$PROFILE_ID" ]; then
|
||||||
[ "$PROFILE_ID" = none ] && PROFILE_ID=
|
[ "$PROFILE_ID" = none ] && PROFILE_ID=
|
||||||
LOOKUP=done
|
LOOKUP=done
|
||||||
fi
|
fi
|
||||||
lookup_profile() { # $1 = log suffix; sets PROFILE_ID, LOOKUP=done on a usable list
|
lookup_profile() { # $1 = modem state, $2 = log suffix; sets PROFILE_ID, LOOKUP=done on a final answer
|
||||||
[ "$LOOKUP" = done ] && return 0
|
[ "$LOOKUP" = done ] && return 0
|
||||||
if OUT=$(qmicli -d qrtr://0 --wds-get-profile-list=3gpp 2>&1); then
|
if OUT=$(qmicli -d qrtr://0 --wds-get-profile-list=3gpp 2>&1); then
|
||||||
# a list with no profiles at all is the modem still coming up, not
|
# a list with no profiles at all is the modem still coming up, not
|
||||||
# a modem without an ims profile (dev phone cold boot 2026-09-20
|
# a modem without an ims profile (dev phone cold boot 2026-09-20
|
||||||
# 16:47: exit 0, no entries, index 2 present a minute later)
|
# 16:47: exit 0, no entries, index 2 present a minute later)
|
||||||
if ! printf '%s\n' "$OUT" | grep -q -E '^[[:space:]]*\[[0-9]+\] 3gpp'; then
|
if ! printf '%s\n' "$OUT" | grep -q -E '^[[:space:]]*\[[0-9]+\] 3gpp'; then
|
||||||
log "ims profile lookup returned no profiles$1"
|
log "ims profile lookup returned no profiles$2"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
PROFILE_ID=$(printf '%s\n' "$OUT" | awk -v apn="$IMS_APN" '
|
PROFILE_ID=$(printf '%s\n' "$OUT" | awk -v apn="$IMS_APN" '
|
||||||
/^[ \t]*\[[0-9]+\] 3gpp/ { idx = $1; gsub(/[^0-9]/, "", idx) }
|
/^[ \t]*\[[0-9]+\] 3gpp/ { idx = $1; gsub(/[^0-9]/, "", idx) }
|
||||||
/APN:/ { a = $0; sub(/.*APN: '"'"'/, "", a); sub(/'"'"'.*/, "", a);
|
/APN:/ { a = $0; sub(/.*APN: '"'"'/, "", a); sub(/'"'"'.*/, "", a);
|
||||||
if (tolower(a) == tolower(apn) && idx != "") { print idx; exit } }')
|
if (tolower(a) == tolower(apn) && idx != "") { print idx; exit } }')
|
||||||
|
if [ -n "$PROFILE_ID" ]; then
|
||||||
LOOKUP=done
|
LOOKUP=done
|
||||||
[ -n "$PROFILE_ID" ] && log "ims profile: index $PROFILE_ID (apn $IMS_APN)" || log "ims profile: none for apn $IMS_APN, connecting by APN string"
|
log "ims profile: index $PROFILE_ID (apn $IMS_APN)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# a list without the APN is final only once the modem is registered:
|
||||||
|
# while it enables, the list can be partial (dev phone cold boot
|
||||||
|
# 2026-09-24 18:18: entries but no ims at `enabling`, ims listed when
|
||||||
|
# read minutes later), and on a walled carrier the APN-string fallback
|
||||||
|
# that would follow is the request the modem refuses
|
||||||
|
case "$1" in
|
||||||
|
registered|connecting|connected)
|
||||||
|
LOOKUP=done
|
||||||
|
log "ims profile: none for apn $IMS_APN, connecting by APN string" ;;
|
||||||
|
*) log "ims profile: not in the list yet$2" ;;
|
||||||
|
esac
|
||||||
else
|
else
|
||||||
log "ims profile lookup failed$1: $(squash "$OUT")"
|
log "ims profile lookup failed$2: $(squash "$OUT")"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
lookup_profile " (modem state: $(modem_state))"
|
STATE=$(modem_state)
|
||||||
|
lookup_profile "$STATE" " (modem state: $STATE)"
|
||||||
|
|
||||||
# ---- find a connected ims bearer; else find-or-create one and connect it.
|
# ---- find a connected ims bearer; else find-or-create one and connect it.
|
||||||
# APN names are case-insensitive. A DISCONNECTED bearer is reused only when
|
# APN names are case-insensitive. A DISCONNECTED bearer is reused only when
|
||||||
|
|
@ -157,12 +172,14 @@ if [ -z "$BEARER" ]; then
|
||||||
waited=$((waited + 5))
|
waited=$((waited + 5))
|
||||||
done
|
done
|
||||||
log "modem state: $(modem_state), packet service: $(packet_state)"
|
log "modem state: $(modem_state), packet service: $(packet_state)"
|
||||||
# a lookup that failed while the modem was still coming up
|
# a lookup with no final answer yet: it failed, or its list lacked the
|
||||||
|
# APN while the modem was still coming up
|
||||||
n=0
|
n=0
|
||||||
while [ "$LOOKUP" != done ] && [ "$n" -lt 3 ]; do
|
while [ "$LOOKUP" != done ] && [ "$n" -lt 3 ]; do
|
||||||
n=$((n + 1))
|
n=$((n + 1))
|
||||||
sleep 5
|
sleep 5
|
||||||
lookup_profile " (retry $n)"
|
STATE=$(modem_state)
|
||||||
|
lookup_profile "$STATE" " (retry $n, modem state: $STATE)"
|
||||||
done
|
done
|
||||||
if [ "$LOOKUP" != done ]; then
|
if [ "$LOOKUP" != done ]; then
|
||||||
PROFILE_ID=
|
PROFILE_ID=
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue