Ncm detect retry - #25286
Ncm detect retry#25286carlosz1986 wants to merge 4 commits into
Conversation
The same gcom call and awk filter were copy-pasted four times: manufacturer and model in proto_ncm_setup(), and again in proto_ncm_teardown() for the path that re-detects when the ubus data is gone. Collapse them into ncm_query_id(), which takes the gcom script and the AT command tag. No functional change. Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
The reply to AT+CGMI/AT+CGMM was taken to be the first line that is not the
command echo, whatever that line happened to be. A modem that has just been
powered up is still emitting unsolicited result codes on the same port, so
that line is often one of those.
Probing a Quectel EG060W once a second with nothing else on the port, from
the moment its /dev/ttyUSB2 appears:
[+15s] CGMI[] CGMM[ OK AT*APPOWERIND=0;*POWERIND=0 +CESQ: 99,99,255,255,
255,255 ^MODE:0,0 +CIREPI: 0 *BANDIND: OK AT+CGMI Quectel OK
AT+CGMM EG060W-EAAA OK ]
[+18s] CGMI[AT+CGMI Quectel OK RDY ] CGMM[AT+CGMM EG060W-EAAA OK ]
[+20s] CGMI[AT+CGMI Quectel OK ] CGMM[AT+CGMM EG060W-EAAA OK ]
Two ways that goes wrong. A URC can become the manufacturer - had the read
window at +18s opened a moment later, RDY would have been the first line -
and then no profile matches, "Unsupported modem" is reported and
proto_set_available 0 makes it permanent. Or a stray OK becomes the model,
as in the +15s capture, and the model specific profile is silently missed.
Skip command echoes, URCs and bare status lines, and anchor the answer on
the echo of the command that was sent so that a backlog holding both
exchanges is still parsed correctly. Modems with echo off have no such
anchor, so keep the first plausible line as a fallback.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
27e4f45 to
33be06f
Compare
Identification was attempted once unless the delay option was set, and config_generate never sets it for an ncm interface. The tty hotplug handler calls proto_set_available 1 as soon as the port is recreated, so setup runs while the modem is still coming up. On a Quectel EG060W the port appears 15s after power-on and AT+CGMI answers nothing at all for the first few seconds: Interface 'wwan' is setting up now wwan (4950): Unsupported modem wwan (4997): Stopping network wwan Interface 'wwan' is now down proto_set_available 0 is called on that path, so netifd does not try again and the interface stays down until someone runs ifup by hand. Keep asking until the modem identifies itself, bounded by one deadline shared by both queries so an absent modem costs one wait and not two. The default of 20s is measured rather than guessed. On this board the port appears 21s into the boot and the modem needs roughly five more seconds before it answers cleanly, which took three attempts at about 2.6s each: identification completed 9s after setup started, on two consecutive boots. A deadline only bounds how long we keep trying, since success leaves the loop immediately, so the headroom is free. delay still overrides it. The model is now retried as well. It never was, which left it dependent on a single reply landing cleanly, and a modem that reports no model at all still falls back to its manufacturer entry once the deadline passes. Report what was actually read when giving up, because "Unsupported modem" on its own says nothing about why. A modem that reports no model at all would otherwise wait out the whole deadline on every bring-up, so only insist on one while ncm.json actually has a "<manufacturer>-<model>" entry that could match it. Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
ncm.sh dials whatever the modem says and hands the interface to netifd without ever asking whether there is a network. A modem in limited service answers the dial command happily, cdc_ncm raises carrier as soon as the netdev is enabled, and udhcpc is then left broadcasting into nothing: +CGATT: 0 +CGPADDR: 1,"" +QENG: "servingcell","LIMSRV",... wwan_4: udhcpc: broadcasting discover (repeating, no lease, interface "up") Ask AT+CGATT? until the modem reports it is attached, and fail the setup if it never does, so netifd tears down, sends the disconnect and tries again instead of reporting an interface that cannot pass traffic. This is the same shape qmi.sh uses for registration, including its NETWORK_REGISTRATION_FAILED error and leaving proto_block_restart alone so that retries continue. AT+CGATT? is 3GPP 27.007, but a modem that does not answer it is not held up: an empty reply skips the check. attachwait sets the budget in seconds and defaults to 10; 0 turns the check off. The name avoids qmi.sh's timeout, where 0 means wait forever rather than do not wait. Two alternatives did not work out. AT+CGPADDR cannot be used because the LTE default bearer already carries an address at attach, on Quectel and Fibocom alike, so the check would pass immediately. getcarrier.gcom already polls AT+CGATT?, and treats a silent modem the same way this does, but its timeout is a fixed ~20s that cannot be passed in, and it is shared with directip.sh and 3g.sh, so giving it a deadline would change behaviour for two other protocols. runquery.gcom is added because runcommand.gcom reports only an exit status, so no caller could look at what the modem actually replied. Not every profile can be gated this way: samsung dials with AT+CGATT=1, so waiting for AT+CGATT? to report 1 beforehand would never let it connect at all. Mark such profiles attachatconnect, in the same spirit as linkatfinalize, and skip the wait for them. Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
33be06f to
ef6bf7a
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Commit checks
- c4a2a56 "comgt: ncm: factor modem identification into a helper" — "No functional change" is not accurate: the teardown manufacturer probe had no
[ "$manufacturer" = "error" ]normalisation before, so a modem answering ERROR there now returns GETINFO_FAILED instead of falling through to the profile lookup. Either note the behaviour change or keep that path byte-identical.
Generated by Claude Code
| state=$(COMMAND="AT+CGATT?" gcom -d "$device" -s /etc/gcom/runquery.gcom | \ | ||
| awk -v RS='\r?\n' '/\+CGATT: [0-9]/ { sub(/.*\+CGATT: /, ""); print $1 + 0; exit }') | ||
|
|
||
| [ -z "$state" ] && return 0 |
There was a problem hiding this comment.
An empty reply cannot be distinguished from a slow one here: runquery.gcom uses get 1 "" $s, so any answer that does not land inside that 1 s window yields an empty $state and silently disables the attach gate for the whole setup — on the first probe, in exactly the just-powered-up race the rest of the series is about. Consider only bailing out fail-open after the modem has been seen to answer something (or after N empty probes), rather than on the first one.
Generated by Claude Code
| [ -z "$attachatconnect" ] && [ "${attachwait:-10}" -gt 0 ] && { | ||
| ncm_wait_attach "$device" $(($(date +%s) + ${attachwait:-10})) || { | ||
| echo "Modem did not attach to the network" | ||
| proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED | ||
| return 1 | ||
| } | ||
| } |
There was a problem hiding this comment.
Failing setup here makes netifd re-run initialize/configure on every retry, and for the mikrotik profile configure is AT+CFUN=4 … AT+CFUN=1 — a radio restart. With the 10 s default that profile can be pushed into a loop where the radio is cycled before it ever gets the chance to attach, on a board that previously came up (slowly). Either give such profiles a larger default, or attachatconnect-style opt-out, or move the wait ahead of configure?
Generated by Claude Code
|
Tried the parser on the other vendor, as asked. Setup: built this branch's Identification works, and it takes a path yours probably does not. This modem answers without a prefix and does echo the command: so nothing matches
The retry does what it says. After the reset, hotplug starts setup while the modem is still booting, and the log shows exactly the sequence you describe, then recovery: Recovery after The first one did not: interface up, no lease, and nothing retried. The modem was fully registered at that point — One structural note, not an objection. Also confirming the collision you flagged: this and #24974 both take Tested-by: Fredrik Hallin fredappsdev@outlook.com |
Fixes #25285
ncm.sh asks the modem who it is with AT+CGMI and AT+CGMM and takes the first line that is not the echo. A modem that just booted is still printing unsolicited stuff on the same port, so that line is often a URC and not the vendor. Then the interface is marked unsupported, proto_set_available 0 is called, and netifd never tries again until someone runs ifup by hand.
While testing I also noticed ncm.sh dials even when the modem has no network at all, so udhcpc just broadcasts into nothing.
delay, and config_generate never doesquectelinstead ofquectel-eg060wHow to reproduce: with wwan up, power cycle the modem. The tty hotplug script calls proto_set_available 1 as soon as the port is back, so setup runs while the modem is still printing. Doing an ifdown first hides it.
With the patches the same power cycle just works.
New options:
Costs one extra AT command on a healthy modem, about 1.5s. linksettle is not touched.
Tested on a Cudy LT700 Outdoor v1 with a Quectel EG060W, on a real image with comgt 0.32-r38:
Not tested because I have no hardware: samsung and mikrotik. samsung is the one with attachatconnect so that part is reasoning, not a measurement. On mikrotik attach starts late so 10s might be tight, attachwait can be raised.
Not in here: linksettle is unchanged, I have a follow-up using force_link on the DHCP sub-interfaces that would remove the wait completely but it needs more testing. If the modem loses the network after it came up nothing recovers it, that is not new and not fixed here. waitforconnect in ncm.json has never been read by ncm.sh since 2023, left alone.
(I used some LLM to summarize the PR - validating, review and testing was done by me)
@FredApps this bumps PKG_RELEASE to 38 like your #24974, so whoever is second needs a small rebase, and you are the only one who can try the parser on another vendor. @patrakov this is the check you were ok with. @jonasjelonek you merged
#24689, this is the follow-up. @jlabuz @Leo-PL @blocktrron if you have time.