Procedure: DetermineLocation (NlmfLocation — UE Cell-ID Positioning)
Spec: TS 23.273 §6 (architecture) · §7.2 (UE positioning) · §9.1 (location privacy) · TS 29.572 §5.2.2.2 (Nlmf_Location DetermineLocation) · TS 29.518 §5.2.2.6 (Namf_Location producer) · TS 38.413 §8.17.1 (NGAP LocationReportingControl / LocationReport) · TS 23.501 §6.2.18 (LMF) · TS 29.503 §5.2.2 (Nudm_SDM lcsData) · TS 29.510 §6.1.6.3.3 (NRF NFType=LMF) Status: ✅ Implemented (Cell-ID + Deferred MT Location + Location Privacy) Primary NF: LMF (Nlmf_Location producer) Other NFs involved: AMF (Namf_Location producer + NGAP relay to RAN), gNB, UE, LCS Client (5GC-internal consumer of Nlmf)
Context
Section titled “Context”The Location Management Function (LMF) is the 5GC NF responsible for UE positioning (TS 23.501 §6.2.18). It lives entirely in the core network and reaches the RAN only through the AMF acting as an NGAP relay — the LMF never has a direct N2 (NGAP/SCTP) association to the gNB.
This procedure implements Cell-ID positioning (TS 23.273 §7.2), Deferred MT Location paging-then-locate (TS 23.273 §7.2 steps E2–E7), and Location Privacy (TS 23.273 §9.1). The serving cell of the UE (its NRCGI + TAI, reported by the gNB) is returned as the location estimate. LPP/NRPPa and GMLC remain deferred (see Out of scope).
Two NFs participate:
- LMF (
nf/lmf/, SBI port 8012, Prometheus 9113): hosts theNlmf_LocationDetermineLocationendpoint. On request it calls the AMF’sNamf_Locationproducer to obtain the UE’s current serving cell, maps NRCGI→coordinates, and returnsLocationData. - AMF (
nf/amf/, existing SBI port 8001): hosts a newNamf_Locationproducer endpoint. On receipt it builds and sends an NGAP LocationReportingControl (ProcCode=16) to the UE’s serving gNB, then blocks until the matching NGAP LocationReport (ProcCode=18) arrives, decodesUserLocationInformationNR→ NRCGI + TAI, and returns it.
Endpoints
Section titled “Endpoints”| Service | Producer | Endpoint |
|---|---|---|
Nlmf_Location |
LMF (:8012) | POST /nlmf-loc/v1/ue-contexts/{ueContextId}/provide-loc-info |
Namf_Location |
AMF (:8001) | POST /namf-loc/v1/ue-contexts/{ueContextId}/provide-loc-info |
{ueContextId} is the UE identifier (imsi-<digits> SUPI, or a 5G-GUTI form) the consumer
supplies. The AMF resolves it to an active UE context to obtain the AMF-UE-NGAP-ID /
RAN-UE-NGAP-ID pair and the serving gNB association.
Specifications
Section titled “Specifications”| Topic | Reference |
|---|---|
| LMF functional description | TS 23.501 §6.2.18 |
| Location services architecture | TS 23.273 §6 |
| UE positioning procedure | TS 23.273 §7.2 |
| Nlmf_Location DetermineLocation (stage 3) | TS 29.572 §5.2.2.2 |
| LocationData / RequestLocInfo data model | TS 29.572 §6.1.6.2.2 |
| Namf_Location ProvideLocationInfo (AMF producer) | TS 29.518 §5.2.2.6 |
| NGAP LocationReportingControl / LocationReport | TS 38.413 §8.17.1 |
| NRF registration NFType=LMF | TS 29.510 §6.1.6.3.3 |
NF interaction overview
Section titled “NF interaction overview”LCS Client ──Nlmf_Location──▶ LMF ──Namf_Location──▶ AMF ══NGAP (N2 relay)══▶ gNB │ ▲ │ │◀──── LocationData ────┘◀── NGAP LocationReport ─┘- Nlmf_Location (SBI, mTLS+HTTP/2): LCS Client / requesting NF → LMF.
- Namf_Location (SBI, mTLS+HTTP/2): LMF → AMF (LMF is the consumer here).
- NGAP N2 (SCTP): AMF ↔ gNB. The AMF is the only NF with an N2 association; it relays the positioning control and report on behalf of the LMF.
Sequence Diagram
Section titled “Sequence Diagram”Each message is annotated with its governing TS section. [M] = mandatory step in the
Cell-ID flow; [C] = conditional; [D] = deferred MT Location (paging sub-flow).
sequenceDiagram
participant LCS as LCS Client / Consumer
participant LMF
participant UDM
participant AMF
participant gNB
participant UE
Note over LCS,LMF: TS 29.572 §5.2.2.2 — Nlmf_Location DetermineLocation
LCS->>LMF: [M] POST /nlmf-loc/v1/ue-contexts/{id}/provide-loc-info<br/>RequestLocInfo {supi/gpsi, locationQoS, priority}
Note over LMF: TS 23.273 §7.2 — select positioning method = Cell-ID
Note over LMF,UDM: TS 23.273 §9.1 — Location Privacy check (if privacy_check=true)
LMF->>UDM: [C] GET /nudm-sdm/v2/{supi}/lcs-privacy-data
UDM-->>LMF: [C] 200 OK {locationPrivacy: "ALLOW_ALL"}
Note over LMF: BLOCK_ALL → 403 PRIVACY_EXCEPTION_DENIED (stop)
Note over LMF,AMF: TS 29.518 §5.2.2.6 — Namf_Location ProvideLocationInfo
LMF->>AMF: [M] POST /namf-loc/v1/ue-contexts/{id}/provide-loc-info<br/>RequestLocInfo {req5gsLoc, supportedGADShapes}
Note over AMF: Resolve {id} → UEContext.<br/>Check CM-CONNECTED (N2 association exists).
alt UE is CM-IDLE — Deferred MT Location (TS 23.273 §7.2 steps E2–E7)
Note over AMF: T-positioning guard timer = 15 s
AMF->>gNB: [D] NGAP Paging (ProcCode=24) — 5G-S-TMSI + TAI list
gNB->>UE: [D] RRC Paging
UE->>gNB: [D] RRC: RRCSetupRequest / RRCResumeRequest
gNB->>AMF: [D] NGAP InitialUEMessage — ServiceRequest NAS
AMF->>AMF: [D] handle Service Request → CM-CONNECTED<br/>onUEReachable → NotifyUEReachable(AMF-UE-NGAP-ID)
Note over AMF: Proceed to LocationReportingControl ↓
end
Note over AMF: Insert pending entry keyed by AMF-UE-NGAP-ID.
Note over AMF,gNB: TS 38.413 §8.17.1 — NGAP relay (AMF on behalf of LMF)
AMF->>gNB: [M] NGAP LocationReportingControl (ProcCode=16)<br/>AMF-UE-NGAP-ID(10), RAN-UE-NGAP-ID(85),<br/>LocationReportingRequestType(33): EventType=Direct, ReportArea=Cell
gNB->>AMF: [M] NGAP LocationReport (ProcCode=18)<br/>AMF-UE-NGAP-ID(10), RAN-UE-NGAP-ID(85),<br/>UserLocationInformation(121) → UserLocationInformationNR(NRCGI + TAI)
Note over AMF: Decode ULI-NR → NRCGI + TAI.<br/>Resolve pending channel by AMF-UE-NGAP-ID.
AMF-->>LMF: [M] 200 OK Namf LocationData {nrCellId, tai}
Note over LMF: TS 29.572 §6.1.6.2.2 — build LocationData.<br/>Map NRCGI → coordinate (config map) or placeholder.
LMF-->>LCS: [M] 200 OK LocationData {locationEstimate(POINT), nrCellId, ageOfLocationEstimate}
Information Elements
Section titled “Information Elements”Nlmf_Location request — RequestLocInfo (LCS Client → LMF, TS 29.572 §6.1.6.2.x)
Section titled “Nlmf_Location request — RequestLocInfo (LCS Client → LMF, TS 29.572 §6.1.6.2.x)”| IE | Type | M/O | Notes |
|---|---|---|---|
supi |
string | C | UE permanent identity; one of supi/gpsi identifies the UE |
gpsi |
string | C | Generic public subscription identifier (alternative to supi) |
locationQoS |
object | O | Requested accuracy / response-time class (hAccuracy, vAccuracy, responseTime) |
priority |
enum | O | LCS_Priority: HIGHEST_PRIORITY / NORMAL_PRIORITY |
supportedGADShapes |
array | O | GAD shapes the client can decode; MVP returns POINT |
Carried in the path as
{ueContextId}; body conveys the QoS/priority. MVP usessupi.
Namf_Location request — RequestLocInfo (LMF → AMF, TS 29.518 §6.1.6.2.x)
Section titled “Namf_Location request — RequestLocInfo (LMF → AMF, TS 29.518 §6.1.6.2.x)”| IE | Type | M/O | Notes |
|---|---|---|---|
req5gsLoc |
boolean | M | Request 5GS location (TAI + NRCGI of the serving cell) |
reqCurrentLoc |
boolean | O | Request the current (not last-known) location → triggers fresh NGAP report |
supportedGADShapes |
array | O | GAD shapes the consumer accepts |
Namf_Location response — LocationData (AMF → LMF) / Nlmf response (LMF → LCS), TS 29.572 §6.1.6.2.2
Section titled “Namf_Location response — LocationData (AMF → LMF) / Nlmf response (LMF → LCS), TS 29.572 §6.1.6.2.2”| IE | Type | M/O | Notes |
|---|---|---|---|
locationEstimate |
object | M | GeographicArea: {shape:"POINT", point:{lat, lon}} for MVP |
nrCellId |
string | C | Serving cell, NRCGI rendered as hex (36-bit cell id) |
tai |
object | C | Tracking Area Identity {plmnId:{mcc,mnc}, tac} |
ageOfLocationEstimate |
integer | O | Minutes since the estimate; 0 for a fresh report |
positioningDataList |
array | O | Methods used; MVP reports cellID |
Example MVP body:
{ "locationEstimate": { "shape": "POINT", "point": { "lat": 0, "lon": 0 } }, "nrCellId": "000000010", "ageOfLocationEstimate": 0}For Cell-ID,
lat/lonare derived from a config mapplmn→cell→coord; when no entry exists,lat=0, lon=0is an acceptable placeholder (the authoritative output isnrCellId).
NGAP LocationReportingControl — ProcedureCode 16 (AMF → gNB, TS 38.413 §8.17.1, §9.2.x)
Section titled “NGAP LocationReportingControl — ProcedureCode 16 (AMF → gNB, TS 38.413 §8.17.1, §9.2.x)”UE-associated, class-1-less control message; carried on the existing N2 association.
| IE (id) | M/O | Notes |
|---|---|---|
| AMF-UE-NGAP-ID (10) | M | AMF-side UE association id |
| RAN-UE-NGAP-ID (85) | M | gNB-side UE association id |
| LocationReportingRequestType (33) | M | EventType = Direct (0) (report once now); ReportArea = Cell (0) |
NGAP LocationReport — ProcedureCode 18 (gNB → AMF, TS 38.413 §8.17.1)
Section titled “NGAP LocationReport — ProcedureCode 18 (gNB → AMF, TS 38.413 §8.17.1)”| IE (id) | M/O | Notes |
|---|---|---|
| AMF-UE-NGAP-ID (10) | M | Correlation key for the pending request map |
| RAN-UE-NGAP-ID (85) | M | gNB-side UE association id |
| UserLocationInformation (121) | M | UserLocationInformationNR → NRCGI (PLMN + 36-bit cell id) + TAI (PLMN + TAC) |
| LocationReportingRequestType (33) | O | Echo of the requested reporting type |
Error / cause table
Section titled “Error / cause table”| Trigger | NF | HTTP | Cause | Behaviour |
|---|---|---|---|---|
{ueContextId} has no UE context in the AMF |
AMF | 404 | CONTEXT_NOT_FOUND |
Namf_Location rejected; LMF propagates failure to LCS Client |
| UE is CM-IDLE — paging initiated, UE responds | AMF | — | — | AMF pages UE (NGAP Paging ProcCode=24); waits T-positioning (15 s); on Service Request falls through to LocationReportingControl |
| UE is CM-IDLE — paging timeout (T-positioning 15 s) | AMF | 504 | UE_NOT_REACHABLE |
UE did not respond to paging; pendingLocPage channel closed; error returned |
| No NGAP LocationReport before timeout | AMF | 504 | LOCATION_FAILURE |
Pending channel closed on ctx deadline; failure result returned |
| gNB returns failure / cannot determine cell | AMF | 504 | POSITIONING_DENIED / UNSPECIFIED |
Decoded error relayed as failure |
Subscriber location privacy = BLOCK_ALL (UDM lcsData) |
LMF | 403 | PRIVACY_EXCEPTION_DENIED |
LMF refuses to disclose location; AMF is never called. Ref: TS 23.273 §9.1 |
| UDM unreachable during privacy check | LMF | — | — | Fail-open: location proceeds (warning logged) |
| Missing mandatory IE in the request body | LMF / AMF | 400 | MANDATORY_IE_MISSING |
Request rejected before any NGAP signalling |
UE not identifiable (supi/gpsi both absent) |
LMF | 400 | MANDATORY_IE_MISSING |
Rejected at the Nlmf producer |
| LMF cannot reach AMF / AMF discovery fails | LMF | 504 | LOCATION_FAILURE |
Returned to LCS Client |
Cause/status names follow TS 29.572 §6.1.x and TS 29.571 ProblemDetails; where a 3GPP cause string is not pinned down for Cell-ID MVP it is noted as
[VERIFY: clause unclear].[VERIFY: clause unclear]— exact ProblemDetailscauseenum for positioning timeout in TS 29.572 (vs. genericTIMED_OUT) to be confirmed against the Rel-17 YAML.
Implementation notes (for the NF developer)
Section titled “Implementation notes (for the NF developer)”- LMF NF (
nf/lmf/): root-module member (no per-NFgo.mod; importsgithub.com/.../claudia-5gc/...), template Dockerfile shape, SBI :8012, Prometheus :9113. Wire into CI docker matrix, rootMakefileNFS :=, anddocker-compose.yml(service +pcap-lmfsidecar,profiles: [core]). Addlmftogen-pki.sh. - NRF registry: add
NFTypeLMF NFType = "LMF"andNFTypeGMLC NFType = "GMLC"constants tonf/nrf/internal/registry/registry.go. LMF registers with servicenlmf-loc(TS 29.510 §6.1.6.3.3). - AMF Namf_Location producer: new handler on the existing :8001 SBI server,
POST /namf-loc/v1/ue-contexts/{id}/provide-loc-info. Resolve{id}→UEContext; require CM-CONNECTED (an N2 association with aRAN-UE-NGAP-ID). - Pending-request correlation:
sync.Mapkeyed byAMF-UE-NGAP-ID→chan LocationResult. The Namf_Location handler (1) inserts the channel, (2) builds + sends NGAP LocationReportingControl, (3) blocks on the channel with actxtimeout (recommend a dedicated positioning timeout constant with a TS doc comment). The NGAP LocationReport handler looks up the channel byAMF-UE-NGAP-ID, decodesUserLocationInformationNR, and resolves it. Alwaysdeferdeletion of the map entry to avoid leaks on timeout. - NGAP builder/decoder: builder for LocationReportingControl (ProcCode=16, EventType=Direct, ReportArea=Cell); decoder for LocationReport (ProcCode=18) extracting NRCGI (PLMN + 36-bit cell id) and TAI (PLMN + TAC). Keep the NGAP code in the AMF reference-point package, separate from SBI handlers (anti-pattern: mixing SBI and N2 in one handler).
- NRCGI rendering: NRCGI hex string for
nrCellId; coordinate mapping via a config map (plmn → cell → {lat,lon}). Absent mapping →POINTwithlat=0,lon=0. - Logging:
logging.NewProcedureLogger(ctx, "DetermineLocation").nf=LMF/AMF;interface=Nlmf/Namf/N2;spec_refper step (e.g.TS 38.413 §8.17.1). Conditional fields:supi,amf_ue_ngap_id,ran_ue_ngap_id,result,cause,duration_ms. - Metrics:
fivegc_lmf_locate_total{result}on :9113.
Out of scope (deferred — follow-up tasks LMF-003+)
Section titled “Out of scope (deferred — follow-up tasks LMF-003+)”- LPP / NRPPa relay for E-CID / OTDOA / NR-ECID / GNSS (TS 38.413 §8.17.2, TS 37.355).
- Nlmf_Location EventSubscription / periodic / area-of-interest (TS 29.572 §5.2.3).
- CancelLocation (TS 29.572 §5.2.2.5).
- GMLC integration / N56 interface (TS 29.515).
- Fine-grained privacy exception lists (
lcsPrivacyExceptionListper-service-class). Current impl enforcesALLOW_ALLvsBLOCK_ALLonly. - Nlmf_Broadcast service for OTDOA assistance (TS 29.572 §5.3).
- LocationContextTransfer during handover (TS 23.273 §7.8).
Validation approach
Section titled “Validation approach”- Unit (in-process): the LocationReportingControl builder encodes to a valid NGAP PDU
that round-trips through the free5gc/ngap decoder (IEs 10/85/33 present, EventType=Direct,
ReportArea=Cell). The LocationReport decoder extracts NRCGI + TAI from a captured
UserLocationInformationNR. DetermineLocation handler maps a known NRCGI → expectedLocationData. - Functional (godog, ≥3 scenarios): happy path (200 +
nrCellId); UE-not-found → 404CONTEXT_NOT_FOUND; gNB-location-failure / timeout → failure result. AMF pending-map correlation tested with a simulated async LocationReport. - NRF registration: LMF registers as
NFType=LMFwith servicenlmf-loc; discoverable by the LCS Client / consumer. - mTLS + HTTP/2: both Nlmf and Namf endpoints set
TLSConfig(NextProtos: ["h2"]) beforehttp2.ConfigureServerand require client certs (TS 29.500 §4.4, TS 33.501 §13). - E2E (UERANSIM):
make ueransim→ register UE + PDU session → POST/nlmf-loc/v1/ue-contexts/imsi-001010000000001/provide-loc-info→ expect the serving NRCGI/TAI and a non-zero lat/lon in the response (scripts/validate-ueransim-mod.sh location). Note: stock UERANSIM v3.2.8 gNB has no LocationReportingControl handler — it logs “Unhandled NGAP initiating-message” and never replies, so the flow times out. The gNB patchtools/ueransim/patches/0040-location-reporting.patch(LMF-006) addsreceiveLocationReportingControl(), which answers with a Cell-ID-level LocationReport. Build it withmake ueransim-build-only.
Coordinate synthesis & live monitoring (LMF-006)
Section titled “Coordinate synthesis & live monitoring (LMF-006)”Cell-ID positioning carries only the serving cell (NRCGI/TAI) on the N2/NGAP wire — no lat/lon.
The LMF synthesizes a WGS84 coordinate from the serving cell via a mobility model
(nf/lmf/internal/server/mobility.go): a deterministic, bounded, per-SUPI walk anchored at the
cell’s configured base coordinate (cell_coordinates / default_coordinate / mobility in
nf/lmf/config/dev.yaml). Values are artificial but exhibit realistic, continuous motion; the
authoritative output remains the serving cell. The horizontal accuracy is reported in
locationEstimate.uncertainty (metres).
The management portal exposes a UE Location page (live Leaflet map + table, auto-poll 3 s)
backed by GET /api/v1/location/summary and /location/ue/{supi}, which act as an LCS client of
the LMF over mTLS. CM-IDLE/unreachable UEs are listed with their 3GPP cause.
Made and developed by Francisco Javier Curieses Sanz · Docs mirrored from claudia-5gc @ v2.3.1