OmniLCS Configuration Reference
All configuration is defined in config/config.exs. This document covers every configuration section and parameter.
Control Panel (LiveView UI)
The Control Panel provides the web-based management interface served over HTTPS on port 443.
config :control_panel,
parent_application: :omnilcs,
parent_application_version: "1.0.0",
parent_application_readable_name: "OmniLCS",
home_page: ControlPanelWeb.ApplicationLive,
use_builtin_pages: [...],
use_additional_pages: [...],
page_order: ["/dashboard", "/location", "/cells", "/diameter",
"/cbc", "/cbc4g", "/application", "/configuration", "/log"],
licensee_name: "Omnitouch"
| Parameter | Type | Description |
|---|---|---|
parent_application | atom | OTP application name |
parent_application_version | string | Version displayed in the UI |
parent_application_readable_name | string | Human-readable product name |
home_page | module | Default landing page module |
use_builtin_pages | list | Built-in pages (Application, Configuration, Log) |
use_additional_pages | list | Custom OmniLCS pages (Dashboard, Location, Cells, Diameter, CBC 2G, CBC 3G, CBC 4G, CAP Alerts) |
page_order | list | Tab ordering in the navigation bar |
licensee_name | string | Licensee name displayed in the footer |
Control Panel Endpoint
config :control_panel, ControlPanelWeb.Endpoint,
server: true,
https: [
port: 443,
keyfile: "priv/cert/omnitouch.pem",
certfile: "priv/cert/omnitouch.crt"
],
secret_key_base: "...",
check_origin: false,
pubsub_server: ControlPanel.PubSub,
live_view: [signing_salt: "LcsLvSlt"]
| Parameter | Type | Default | Description |
|---|---|---|---|
server | boolean | true | Enable the HTTP server |
https.port | integer | 443 | HTTPS listen port |
https.keyfile | string | "priv/cert/omnitouch.pem" | Path to TLS private key |
https.certfile | string | "priv/cert/omnitouch.crt" | Path to TLS certificate |
secret_key_base | string | -- | Phoenix session encryption key (generate with mix phx.gen.secret) |
check_origin | boolean | false | Whether to validate WebSocket origins |
pubsub_server | atom | ControlPanel.PubSub | PubSub server for LiveView updates |
live_view.signing_salt | string | "LcsLvSlt" | LiveView token signing salt |
REST API
The REST API is served over HTTPS on port 8443 via the api_ex framework.
config :api_ex,
api: %{
port: 8443,
listen_ip: "0.0.0.0",
product_name: "OmniLCS",
title: "API - OmniLCS",
hostname: "localhost",
enable_tls: true,
tls_cert_path: "priv/cert/omnitouch.crt",
tls_key_path: "priv/cert/omnitouch.pem",
routes: [...]
}
| Parameter | Type | Default | Description |
|---|---|---|---|
port | integer | 8443 | API listen port |
listen_ip | string | "0.0.0.0" | API bind address |
product_name | string | "OmniLCS" | Product name in OpenAPI spec |
title | string | "API - OmniLCS" | API title in Swagger UI |
hostname | string | "localhost" | Hostname for OpenAPI spec URLs |
enable_tls | boolean | true | Enable HTTPS |
tls_cert_path | string | "priv/cert/omnitouch.crt" | Path to TLS certificate |
tls_key_path | string | "priv/cert/omnitouch.pem" | Path to TLS private key |
routes | list | -- | List of route definitions (path, module, actions) |
Registered API Routes
| Path | Controller | Actions |
|---|---|---|
/status | OmniLcs.Api.StatusController | index |
/location | OmniLcs.Api.LocationController | index, create, show |
/cells | OmniLcs.Api.CellController | index, create, show, update, delete |
/cap | OmniLcs.Api.CapController | index, create, show, update |
E-SMLC Settings
General E-SMLC configuration.
config :omnilcs,
esmlc_name: "OmniLCS",
cell_database_path: "priv/cells.json"
| Parameter | Type | Default | Description |
|---|---|---|---|
esmlc_name | string | "OmniLCS" | E-SMLC instance name (used in status API) |
cell_database_path | string | "priv/cells.json" | Path to cell database JSON file for import |
CBSP (2G Cell Broadcast)
Configuration for the CBSP TCP listener. BSCs connect inbound to the CBC on this port.
config :omnilcs, :cbsp,
listen_ip: "0.0.0.0",
listen_port: 48049
| Parameter | Type | Default | Description |
|---|---|---|---|
listen_ip | string | "0.0.0.0" | IP address to bind the CBSP TCP listener |
listen_port | integer | 48049 | TCP port for CBSP connections (IANA registered port for CBSP) |
SABP (3G Cell Broadcast)
Configuration for the SABP TCP listener. RNCs connect inbound to the CBC on this port via the Iu-BC interface per 3GPP TS 25.419.
config :omnilcs, :sabp,
listen_ip: "0.0.0.0",
listen_port: 3452
| Parameter | Type | Default | Description |
|---|---|---|---|
listen_ip | string | "0.0.0.0" | IP address to bind the SABP TCP listener |
listen_port | integer | 3452 | TCP port for SABP connections from RNCs (IANA-registered, per TS 25.414 §7.1.3.3) |
SBC-AP (4G Cell Broadcast)
Configuration for SBC-AP SCTP connections. Per 3GPP TS 29.168, the CBC initiates SCTP associations to each MME peer.
config :omnilcs, :sbcap,
local_ip: "10.5.198.200",
mme_peers: [
%{host: "mme01", ip: "10.179.2.100", port: 29168},
%{host: "mme02", ip: "10.179.2.101", port: 29168}
]
| Parameter | Type | Default | Description |
|---|---|---|---|
local_ip | string | "0.0.0.0" | Local IP address to bind the SCTP socket |
mme_peers | list | [] | List of MME peer configurations |
MME Peer Configuration
Each entry in mme_peers is a map with the following fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
host | string | No | value of ip | Human-readable MME hostname (for logging and UI) |
ip | string | Yes | -- | MME IP address |
port | integer | No | 29168 | MME SBC-AP SCTP port (IANA registered) |
The SBC-AP transport uses SCTP Payload Protocol Identifier (PPID) 24. On connection failure, it retries with exponential backoff starting at 5 seconds up to a maximum of 60 seconds.
InfluxDB
Cell position data is periodically synchronized from an InfluxDB instance.
config :omnilcs, OmniLcs.InfluxDb,
database: "nokia-monitor",
host: "172.19.3.68",
port: 8086,
auth: [method: :basic, username: "monitor", password: "..."],
http_opts: [recv_timeout: 30_000],
pool: [max_overflow: 10, size: 5]
| Parameter | Type | Default | Description |
|---|---|---|---|
database | string | -- | InfluxDB database name |
host | string | -- | InfluxDB server hostname or IP |
port | integer | 8086 | InfluxDB HTTP API port |
auth.method | atom | :basic | Authentication method |
auth.username | string | -- | InfluxDB username |
auth.password | string | -- | InfluxDB password |
http_opts.recv_timeout | integer | 30000 | HTTP receive timeout in milliseconds |
pool.size | integer | 5 | Connection pool size |
pool.max_overflow | integer | 10 | Maximum pool overflow connections |
Cell sync runs automatically every 5 minutes with an initial delay of 10 seconds after startup. It can also be triggered manually via the REST API or the Control Panel.
SLs Interface (LCS-AP over SCTP)
The SLs interface connects the E-SMLC to the MME using LCS-AP over SCTP per 3GPP TS 29.171. OmniLCS initiates SCTP associations to each configured MME peer on port 9082 with PPID 29.
config :omnilcs, :sls,
local_ip: "10.5.198.200",
mme_peers: [
%{host: "mme01", ip: "10.179.1.15", port: 9082}
]
| Parameter | Type | Default | Description |
|---|---|---|---|
local_ip | string | "0.0.0.0" | Local IP address to bind the SCTP socket |
mme_peers | list | [] | List of MME peer configurations |
MME Peer Configuration (SLs)
Each entry in mme_peers is a map with the following fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
host | string | No | value of ip | Human-readable MME hostname (for logging and UI) |
ip | string | Yes | -- | MME IP address |
port | integer | No | 9082 | MME LCS-AP SCTP port (IANA registered for LCS-AP) |
The SLs transport uses SCTP Payload Protocol Identifier (PPID) 29. On connection failure, it retries with exponential backoff starting at 5 seconds up to a maximum of 60 seconds.
SCTP tuning parameters:
| Parameter | Value | Description |
|---|---|---|
| Heartbeat interval | 10 seconds | Peer address heartbeat |
| Path max retransmissions | 7 | Before declaring path failure |
| RTO max | 30 seconds | Maximum retransmission timeout |
| RTO min | 1 second | Minimum retransmission timeout |
| SACK delay | 200 ms | Selective acknowledgment delay |
Diameter (SLg and Other Interfaces)
The Diameter configuration controls the SLg interface between OmniLCS (acting as GMLC) and the MME, routed through a DRA. This is separate from the SLs interface which uses native LCS-AP over SCTP.
config :diameter_ex,
diameter: %{
service_name: :omnitouch_esmlc,
listen_ip: "10.5.198.200",
listen_port: 3868,
host: "amanaki",
realm: "epc.mnc380.mcc313.3gppnetwork.org",
product_name: "OmniLCS",
request_timeout: 5000,
peer_selection_algorithm: :random,
allow_undefined_peers_to_connect: true,
log_unauthorized_peer_connection_attempts: true,
control_module: OmniLcs.Control.Diameter,
vendor_id: 10415,
supported_vendor_ids: [5535, 10415],
applications: [...],
peers: [...]
}
Service Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
service_name | atom | :omnitouch_esmlc | Diameter service identifier |
listen_ip | string | -- | Local IP address for Diameter transport |
listen_port | integer | 3868 | Diameter listen port (IANA registered) |
host | string | -- | Diameter Origin-Host (without realm suffix) |
realm | string | -- | Diameter Origin-Realm |
product_name | string | "OmniLCS" | Diameter Product-Name AVP value |
request_timeout | integer | 5000 | Request timeout in milliseconds |
peer_selection_algorithm | atom | :random | How to select among multiple peers |
allow_undefined_peers_to_connect | boolean | true | Accept connections from unconfigured peers |
log_unauthorized_peer_connection_attempts | boolean | true | Log unauthorized connection attempts |
control_module | module | OmniLcs.Control.Diameter | Module handling Diameter request routing |
processor_module | module | DiameterEx.Processor | Module processing Diameter messages |
vendor_id | integer | 10415 | 3GPP Vendor-Id |
supported_vendor_ids | list | [5535, 10415] | Supported Vendor-Id values |
Diameter Applications
applications: [
%{
application_name: :slg,
application_dictionary: :diameter_gen_3gpp_slg,
vendor_specific_application_ids: [
%{vendor_id: 10415, auth_application_id: 16_777_264, acct_application_id: nil}
]
}
]
| Field | Type | Description |
|---|---|---|
application_name | atom | Application identifier (:slg for GMLC-to-MME interface) |
application_dictionary | atom | Erlang Diameter dictionary module |
vendor_specific_application_ids | list | Vendor-Specific-Application-Id AVP values |
The SLg application uses Application ID 16777264 with 3GPP Vendor-Id 10415. Note that the E-SMLC-to-MME interface (SLs) uses native LCS-AP over SCTP, not Diameter.
Diameter Peers
peers: [
%{
host: "omni-nick2-dra01.epc.mnc380.mcc313.3gppnetwork.org",
realm: "epc.mnc380.mcc313.3gppnetwork.org",
ip: "10.179.2.233",
port: 3868,
tls: false,
transport: :diameter_sctp,
initiate_connection: true
}
]
| Field | Type | Default | Description |
|---|---|---|---|
host | string | -- | Peer Diameter host identity (FQDN) |
realm | string | -- | Peer Diameter realm |
ip | string | -- | Peer IP address |
port | integer | 3868 | Peer Diameter port |
tls | boolean | false | Enable TLS for the peer connection |
transport | atom | :diameter_sctp | Transport protocol (:diameter_sctp or :diameter_tcp) |
initiate_connection | boolean | true | Whether OmniLCS initiates the connection to this peer |
GMLC / Le Interface
Configuration for the Gateway Mobile Location Centre and Le interface to external LCS clients. See the GMLC & Le Interface Operations Guide for full details on request flows, deferred sessions, and InfluxDB logging.
config :omnilcs, :gmlc,
enabled: true,
allow_unknown_clients: false,
authorized_clients: [
%{
name: "psap-01",
type: :emergency_services,
allowed_methods: [:cell, :ecid, :gnss, :otdoa],
rate_limit: 100,
description: "Primary PSAP"
}
],
allow_deferred: true,
max_periodic_sessions: 100,
max_triggered_sessions: 50,
default_periodic_poll_interval_ms: 60_000,
default_triggered_poll_interval_ms: 30_000,
influx_logging: true
| Parameter | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable the GMLC Le interface handler |
allow_unknown_clients | boolean | false | Accept requests from unlisted clients |
authorized_clients | list | [] | Authorized LCS client definitions (see GMLC guide) |
allow_deferred | boolean | true | Accept periodic and triggered location requests |
max_periodic_sessions | integer | 100 | Maximum concurrent periodic sessions |
max_triggered_sessions | integer | 50 | Maximum concurrent triggered sessions |
default_periodic_poll_interval_ms | integer | 60000 | Default periodic fix interval (ms) |
default_triggered_poll_interval_ms | integer | 30000 | Default geo-fence poll interval (ms) |
influx_logging | boolean | true | Write all GMLC location fixes to InfluxDB |
2G/3G Location (MAP / Lg)
GMLC location for subscribers on GERAN (2G) or UTRAN (3G), reached over the Lg interface using MAP on the omniss7 SS7/SIGTRAN stack. Disabled by default; see 2G/3G location over MAP/Lg.
# OmniLCS MAP/Lg client (OmniLcs.Control.MapClient)
config :omnilcs, :map,
enabled: true,
gmlc_number: "61400000000", # this GMLC's own ISDN number (E.164)
hlr_gt: "61400000001", # HLR global title for SendRoutingInfoForLCS
lcs_client_type: :emergencyServices
# Run the omniss7 SS7 stack as a library (no own web UI / SCTP / license client)
config :omniss7, headless: true
# SS7 transport for the MAP client — the M3UA association to the STP.
# Only needed when :omnilcs, :map is enabled.
config :omniss7, :map_client_enabled, true
config :omniss7, :map_client_m3ua, %{
local_ip: {10, 0, 0, 100},
local_port: 2905,
remote_ip: {10, 0, 0, 1}, # STP / SGP
remote_port: 2905,
routing_context: 1
}
| Parameter | Type | Default | Description |
|---|---|---|---|
:omnilcs, :map enabled | boolean | false | Enable the 2G/3G MAP/Lg location path. When false, rat: "2g"/"3g" requests return 501. |
gmlc_number | string | nil | This GMLC's ISDN number, used as the MAP originator. |
hlr_gt | string | nil | HLR global title for SendRoutingInfoForLCS (serving MSC/SGSN discovery). Not needed if the request supplies node_gt. |
lcs_client_type | atom | :emergencyServices | MAP LCS-ClientType for the request. |
:omniss7 headless | boolean | true (set in config.exs) | Run omniss7 as a library: codec + MAP transaction registry only. |
:omniss7 map_client_m3ua | map | -- | SCTP/M3UA association to the STP/SGP. Required for live operation. |
Accuracy on 2G/3G is Cell-ID / Timing-Advance class. The serving MSC/SGSN returns the serving cell, not a precise fix.
When :omnilcs, :map enabled is true and :map_client_m3ua is set, OmniLCS starts the M3UA association to the STP itself (supervised by OmniLcs.Control.MapStack) — there is no separate transport step. Each MAP transaction is counted by the omnilcs_map_request_total Prometheus metric (tags type, result). If enabled is true but :map_client_m3ua is missing, the transport is skipped with a warning and the rest of OmniLCS is unaffected.
CAP Alerts
Configuration for CAP (Common Alerting Protocol) alert ingestion and broadcast. See the CAP Alert Operations Guide for full details on the alert lifecycle, polygon resolution, and operator approval workflow.
config :omnilcs, :cap,
require_approval: true,
plmn: %{mcc: "001", mnc: "01"},
coverage_aware: false,
feeds: []
| Parameter | Type | Default | Description |
|---|---|---|---|
require_approval | boolean | true | When true, alerts queue for operator approval. When false, alerts auto-broadcast. |
plmn | map | %{mcc: "001", mnc: "01"} | PLMN identity (MCC/MNC) for broadcast messages |
coverage_aware | boolean | false | Use cell coverage radius for polygon intersection (vs center-point only) |
feeds | list | [] | CAP Atom feed URLs to poll |
Feed Configuration
feeds: [
%{url: "https://alerts.weather.gov/cap/us.php?x=1", poll_interval_seconds: 60}
]
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Yes | -- | CAP Atom feed URL |
poll_interval_seconds | integer | No | 60 | Seconds between polls |
Logger
config :logger,
backends: [:console, ControlPanel.Logger]
| Parameter | Type | Description |
|---|---|---|
backends | list | Logger backends. :console writes to stdout; ControlPanel.Logger feeds the Log page in the web UI. |
Complete Configuration Example
import Config
config :control_panel,
parent_application: :omnilcs,
parent_application_version: "1.0.0",
parent_application_readable_name: "OmniLCS",
home_page: ControlPanelWeb.ApplicationLive,
use_builtin_pages: [
{ControlPanelWeb.ApplicationLive, "/application", "Resources"},
{ControlPanelWeb.ConfigurationLive, "/configuration", "Configuration"},
{ControlPanelWeb.LogLive, "/log", "Log"}
],
use_additional_pages: [
{OmniLcs.Web.DashboardLive, "/dashboard", "Dashboard"},
{OmniLcs.Web.LocationLive, "/location", "Location"},
{OmniLcs.Web.CellDatabaseLive, "/cells", "Cells"},
{OmniLcs.Web.DiameterLive, "/diameter", "Diameter"},
{OmniLcs.Web.CbcLive, "/cbc", "CBC 2G"},
{OmniLcs.Web.Cbc3gLive, "/cbc3g", "CBC 3G"},
{OmniLcs.Web.Cbc4gLive, "/cbc4g", "CBC 4G"},
{OmniLcs.Web.CapAlertsLive, "/cap", "CAP Alerts"}
],
page_order: [
"/dashboard", "/location", "/cells", "/diameter",
"/cbc", "/cbc3g", "/cbc4g", "/cap", "/application", "/configuration", "/log"
],
licensee_name: "Omnitouch"
# REST API
config :api_ex,
api: %{
port: 8443,
listen_ip: "0.0.0.0",
product_name: "OmniLCS",
title: "API - OmniLCS",
hostname: "localhost",
enable_tls: true,
tls_cert_path: "priv/cert/omnitouch.crt",
tls_key_path: "priv/cert/omnitouch.pem",
routes: [
%{path: "/status", module: OmniLcs.Api.StatusController, actions: [:index]},
%{path: "/location", module: OmniLcs.Api.LocationController, actions: [:index, :create, :show]},
%{path: "/cells", module: OmniLcs.Api.CellController, actions: [:index, :create, :show, :update, :delete]},
%{path: "/cap", module: OmniLcs.Api.CapController, actions: [:index, :create, :show, :update]}
]
}
# Control Panel HTTPS endpoint
config :control_panel, ControlPanelWeb.Endpoint,
server: true,
url: [host: "0.0.0.0", path: "/"],
https: [port: 443, keyfile: "priv/cert/omnitouch.pem", certfile: "priv/cert/omnitouch.crt"],
adapter: Bandit.PhoenixAdapter,
secret_key_base: "REPLACE_WITH_64_BYTE_RANDOM_SECRET",
check_origin: false,
pubsub_server: ControlPanel.PubSub,
live_view: [signing_salt: "LcsLvSlt"]
# Logger
config :logger,
backends: [:console, ControlPanel.Logger]
# E-SMLC general settings
config :omnilcs,
esmlc_name: "OmniLCS",
cell_database_path: "priv/cells.json"
# CBSP (2G Cell Broadcast) - BSCs connect to this port
config :omnilcs, :cbsp,
listen_ip: "0.0.0.0",
listen_port: 48049
# SABP (3G Cell Broadcast) - RNCs connect to this port
config :omnilcs, :sabp,
listen_ip: "0.0.0.0",
listen_port: 3452
# SLs (LCS-AP over SCTP) - E-SMLC connects to these MMEs for positioning
config :omnilcs, :sls,
local_ip: "10.5.198.200",
mme_peers: [
%{host: "mme01", ip: "10.179.1.15", port: 9082}
]
# SBC-AP (4G Cell Broadcast) - OmniLCS connects to these MMEs
config :omnilcs, :sbcap,
local_ip: "10.5.198.200",
mme_peers: [
%{host: "mme01", ip: "10.179.2.100", port: 29168},
%{host: "mme02", ip: "10.179.2.101", port: 29168}
]
# CAP Alert ingestion and broadcast
config :omnilcs, :cap,
require_approval: true,
plmn: %{mcc: "001", mnc: "01"},
coverage_aware: false,
feeds: []
# InfluxDB for cell position sync
config :omnilcs, OmniLcs.InfluxDb,
database: "nokia-monitor",
host: "172.19.3.68",
port: 8086,
auth: [method: :basic, username: "monitor", password: "REPLACE_WITH_PASSWORD"],
http_opts: [recv_timeout: 30_000],
pool: [max_overflow: 10, size: 5]
# Diameter (SLg interface to DRA/MME - GMLC role, not E-SMLC SLs)
config :diameter_ex,
diameter: %{
service_name: :omnitouch_esmlc,
listen_ip: "10.5.198.200",
listen_port: 3868,
host: "amanaki",
realm: "epc.mnc380.mcc313.3gppnetwork.org",
product_name: "OmniLCS",
request_timeout: 5000,
peer_selection_algorithm: :random,
allow_undefined_peers_to_connect: true,
log_unauthorized_peer_connection_attempts: true,
control_module: OmniLcs.Control.Diameter,
processor_module: DiameterEx.Processor,
auth_application_ids: [],
acct_application_ids: [],
vendor_id: 10415,
supported_vendor_ids: [5535, 10415],
applications: [
%{
application_name: :slg,
application_dictionary: :diameter_gen_3gpp_slg,
vendor_specific_application_ids: [
%{vendor_id: 10415, auth_application_id: 16_777_264, acct_application_id: nil}
]
}
],
peers: [
%{
host: "dra01.epc.mnc380.mcc313.3gppnetwork.org",
realm: "epc.mnc380.mcc313.3gppnetwork.org",
ip: "10.179.2.233",
port: 3868,
tls: false,
transport: :diameter_sctp,
initiate_connection: true
}
]
}