Repository navigation
feat: a timer for NAS procedures, and T3591 resolved for satellite access - #666
Merged
Merged
Conversation
gab-arrobo
force-pushed
the
split/t3591-timer
branch
from
September 25, 2026 18:20
f517367 to
38f2365
Compare
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Stop can return before a concurrently selected expiry callback is suppressed.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Adds foundational T3591 timer support for NAS procedures, including satellite-aware configuration, defaults, and telemetry.
Changes:
- Adds a retry-counting NAS timer.
- Adds terrestrial/satellite T3591 resolution and configuration defaults.
- Adds timer and modification-abandonment metrics.
| File | Summary |
|---|---|
metrics/telemetry.go |
Registers NAS timer and modification metrics. |
factory/t3591_defaults_test.go |
Tests configuration defaulting. |
factory/factory.go |
Applies T3591 defaults. |
factory/config.go |
Defines T3591 configuration. |
context/timer.go |
Implements retry timing; contains a critical stop/callback race. |
context/timer_test.go |
Tests timer expiry and stopping. |
context/nas_timer.go |
Resolves T3591 values and retry settings. |
context/nas_timer_test.go |
Tests timer resolution and defaults. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
gab-arrobo
force-pushed
the
split/t3591-timer
branch
from
September 25, 2026 22:44
38f2365 to
ca5990e
Compare
gab-arrobo
reviewed
Sep 25, 2026
gab-arrobo
left a comment
Contributor
There was a problem hiding this comment.
Here are a few changes/improvements as suggested by Go linter.
Also, is comment #666 (comment) incorrect? Or should it be addressed?
…cess The network-requested PDU session modification procedure needs T3591 (TS 24.501 subclause 10.3): the SMF retransmits the command when the UE does not answer, and gives the procedure up when the retransmissions run out. This is that timer, its configuration and its reporting, with nothing using it yet. The timer is its own type rather than a time.Timer per site, because the procedure needs three things from it that a bare timer does not give: an expiry count, a callback per expiry and one at the end, and a Stop that can be called twice. A procedure that is answered while its last retransmission is in flight stops a timer that has already fired, and that must not panic. The value is resolved from configuration, with a documented fallback, and it depends on whether the UE reaches the network through a satellite NG-RAN cell. TS 24.501 subclause 4.23.4 has the AMF indicate the extended NAS-SM timer for that access, and table 10.3.2 gives T3591 a longer value there. An operator who configures neither gets the specification's terrestrial default rather than zero. A counter of where each value came from is added here for the procedure to report through, so a deployment can tell a configured value from a defaulted one, which is the question asked first when a timer looks wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Edvin Lindqvist <edvin.lindqvist@forsway.com>
…ys what it guarantees The counters use atomic.Int32 instead of int32 fields updated through atomic.AddInt32 and friends, as suggested in review. Stop's comment promised that no expiry follows it, and that was not true. Stop signals the timer's goroutine and returns without waiting. An expiry that is already due can still be delivered, because the goroutine's select picks at random when the stop signal and the ticker are both ready. The comment now says so, and puts the check where it can work: in the caller, which has to confirm that its timer is still the current one, under the lock it holds when it calls Stop. Waiting in Stop for a callback in progress is not an alternative. Callers stop the timer under the same lock their callbacks take, so Stop would wait for a callback that is waiting for it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Edvin Lindqvist <edvin.lindqvist@forsway.com>
gab-arrobo
force-pushed
the
split/t3591-timer
branch
from
September 30, 2026 15:38
2c8ab45 to
2973cc2
Compare
gab-arrobo
reviewed
Sep 30, 2026
gab-arrobo
left a comment
Contributor
There was a problem hiding this comment.
@midwell, please take a look at this comment. Thanks!
context/timer.go is the AMF's timer, ported so that both network functions retransmit on the same semantics. It keeps the free5GC notice the AMF's copy carries, as Apache-2.0 section 4(c) requires, but it had nothing marking what the port changes: the idempotent Stop, the typed atomics, and Stop's documented guarantee. Section 4(b) asks for that notice. It goes above the original one, the order this repository uses where a free5GC file carries a modifier's notice too: ONF's line above free5GC's in producer/sm_pfcp_handling.go, for instance. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Edvin Lindqvist <edvin.lindqvist@forsway.com>
gab-arrobo
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

The first of four pull requests that complete the network-requested PDU session modification procedure, split out of #623. This one adds only T3591 (TS 24.501 subclause 10.3, table 10.3.2): the timer, its configuration and its reporting. Nothing uses it yet; the procedure that does is the next PR.
Why a timer type of its own rather than a
time.Timerat each site. The procedure needs three things from it: an expiry count, a callback per expiry plus one at the end, and aStopthat is safe to call twice. A procedure answered while its last retransmission is in flight stops a timer that has already fired, and that must not panic.The value depends on satellite access. Under TS 24.501 subclause 4.23.4, when the AMF indicates the extended NAS timer for access through a satellite NG-RAN cell, the SMF uses table 10.3.2's longer value. The value is resolved from configuration with a documented fallback, so an operator who configures neither gets the specification's terrestrial default rather than zero. A counter of where each value came from is added here for the next PR to report through. Once sessions report it, a deployment can tell a configured value from a defaulted one, which is the first question asked when a timer looks wrong.
The stack, each PR adding one commit on top of the one before:
Each is rebased onto current
main, after #657, #658 and #660, and each commit passes the gate on its own.Verification.
pre-commit run --all-fileson darwin/arm64 with Go 1.26.0, all nine hooks passing as pinned in.pre-commit-config.yaml:go test -race ./... -count=20,staticcheck,gci, golangci-lint v2.13.2, gitleaks v8.30.1, reuse v6.2.0, yamlfmt v0.21.0 and the whitespace hooks.🤖 Generated with Claude Code