add *3gpp_uli user location converter

Parses the 3GPP-User-Location-Info AVP into structured location data
allowing field access via an optional path (e.g. *3gpp_uli:TAI.MCC).
This commit is contained in:
ionutboangiu
2026-02-10 18:56:59 +02:00
committed by Dan Christian Bogos
parent be08b1d07b
commit 4c64f4f876
6 changed files with 1029 additions and 0 deletions

View File

@@ -136,6 +136,8 @@ func NewDataConverter(params string) (conv DataConverter, err error) {
return ConnStatusConverter{}, nil
case strings.HasPrefix(params, MetaGigawords):
return new(GigawordsConverter), nil
case strings.HasPrefix(params, Meta3GPPULI):
return NewULIConverter(params)
default:
return nil, fmt.Errorf("unsupported converter definition: <%s>", params)
}
@@ -859,3 +861,40 @@ func (c ConnStatusConverter) Convert(in any) (any, error) {
}
return 0, fmt.Errorf("unsupported connection status: %q", status)
}
// ULIConverter decodes 3GPP-User-Location-Info and extracts fields by path.
type ULIConverter struct {
path string
}
// NewULIConverter creates a ULI converter. The path after the colon specifies
// which field to extract (e.g. "*3gpp_uli:TAI.MCC"). Empty path returns the
// full ULI object.
func NewULIConverter(params string) (*ULIConverter, error) {
_, path, _ := strings.Cut(params, InInFieldSep)
return &ULIConverter{path: path}, nil
}
// Convert implements DataConverter interface.
func (c *ULIConverter) Convert(in any) (any, error) {
raw := IfaceAsString(in)
if raw == "" {
return nil, errors.New("empty ULI input")
}
data, err := hex.DecodeString(strings.TrimPrefix(raw, "0x"))
if err != nil {
return nil, fmt.Errorf("invalid ULI hex: %w", err)
}
uli, err := DecodeULI(data)
if err != nil {
return nil, err
}
if c.path == "" {
return uli, nil
}
return uli.GetField(c.path)
}