Custom Data Mapping (Account Info Mapping)

This document is the reference for the Account Info Mapping (Custom Parameters Mapping) on the ACS. The mapping links the values of device parameters (read from the configured parameter paths) to columns of the cust_device1 table (typically cust1 .. cust20) shown in the device list view, with optional per-manufacturer/model scoping and active-connection-relative parameter resolution.

Since 2026-06 the mapping is owned by ft-configs-service and delivered to the ACS as a read-only Hazelcast snapshot. The ACS no longer maintains a local config_custom_data.xml file, does not write the config_custom_data / config_custom_param tables, and exposes no SOAP/file write path for this configuration. See Ownership and Distribution.

1. Overview

Each mapping entry links one custom column to one or more device parameter paths. Several parameters may be listed under one column (e.g. one per data model or per vendor), but only one of them is expected to exist on a given device — its value is the one written to the column. When a device communicates with the ACS (TR-069 Inform, GetParameterValues response, USP notification/registration, MQTT publish), the ACS:

  1. Resolves the mapped parameter paths for the device (taking activeConnection into account).

  2. Subscribes to value changes of the resolved parameters (active notification); when subscriptions are (re)applied, a GetParameterValueList task is also queued to refresh the values from the device (see Processing Flow).

  3. Stores the parameter values into the mapped columns of the cust_device1 table, keyed by device serial number.

The cust_device1 values themselves remain owned by, and stored in, the ACS database — only the mapping definitions moved to ft-configs-service.

2. Ownership and Distribution

Legacy (until 2026-06) Current

Source of truth

ACS database (config_custom_data / config_custom_param), edited via the local config_custom_data.xml file

ft-configs-service database, managed via its REST API (with dry-run import and audit trail)

Distribution to the ACS

local XML file regenerated from the ACS DB; cluster sync via the Hazelcast topic syncConfigCustomData

ft-configs-service publishes a snapshot to the Hazelcast IList config-custom-data; the ACS consumes it read-only

ACS write path

ACS edited the file → synced to its DB → broadcast to the cluster

none — the ACS is a pure consumer

Per-node runtime model

CustomConfigCache existence flags + per-session DB queries (getForManufAndModel, getByIds)

an in-memory near-cache rebuilt from the snapshot, indexed by manufacturer/model (plus a global bucket) — O(1) hot-path lookup, no per-session DB query for mappings

Distribution details:

  • The config-custom-data IList holds a single element — the current snapshot. ft-configs-service replaces it in place (atomic set(0, …​), never leaving the list empty), and the ACS reacts to the republish.

  • The publish happens after the ft-configs-service write transaction commits, so the ACS only ever observes committed state.

  • An empty snapshot (no entries) is a valid state meaning "no mappings — feature disabled"; it is distinct from a missing snapshot (see Availability and Reaction to Changes).

The legacy local file (config_custom_data.xml), its file-change watcher, the syncConfigCustomData topic, and the dead configureAccountInfoMapping / getAccountInfoMapping SOAP methods have been removed. The config_custom_data / config_custom_param tables and their DAOs are deprecated — the ACS neither reads them on the hot path nor writes them; the physical tables are scheduled to be dropped in a later release.

3. Availability and Reaction to Changes

3.1. Startup autonomy

If the snapshot is missing or the Hazelcast cluster is unavailable at startup, the ACS does not fail and does not block readiness:

  • it keeps the last-known near-cache if one is available, otherwise starts with no mappings;

  • it catches up automatically when the snapshot appears (via the cache listener);

  • the degraded state is logged.

An empty snapshot (entries=[]) is a normal "disabled" state, not a degradation.

3.2. Reacting to a snapshot change

When the snapshot changes, every ACS node atomically rebuilds its local near-cache (no empty window).

Device-subscription reconciliation — turning the value-change notification off (notification value 0) for mappings that were removed — is performed by exactly one cluster node (single-owner, gated by a Hazelcast distributed lock), off the cache-event thread, by diffing the new snapshot against the cluster-authoritative previous snapshot. Enabling notifications for added or changed mappings is not done eagerly here — it happens lazily on the affected devices' next session (see Processing Flow). The reconciliation is idempotent and survives node restart and snapshot republish.

4. Mapping Model

A mapping is a list of column entries. Each entry targets one cust_device1 column and carries one or more parameter mappings. (These were previously the <data> and <param> elements of the local XML file; the fields are unchanged.)

4.1. Column entry

Field Type Required Description

column

string

Yes

Target column of the cust_device1 table, typically one of cust1 .. cust20 (any matching cust_device1 column name is accepted). The column is the key of the mapping; matched case-insensitively.

name

string

No

Human-readable column title shown in the device list view (e.g. WANUsername, Inform interval, sec).

A column entry contains one or more parameter mappings. Multiple parameters under one column typically cover different data models (TR-098 vs TR-181) or different manufacturer/model variants. Only one of the listed parameters is expected to exist on any given device — that parameter’s value fills the column.

4.2. Parameter mapping

Field Type Required Description

name

string

Yes

Device parameter path. Interpreted as an absolute path when activeConnection=false, or as a relative suffix under the device’s active connection object when activeConnection=true (see The activeConnection Attribute).

activeConnection

boolean

Yes

Controls how name is resolved to a full parameter path. See The activeConnection Attribute.

manufacturer

string

No

Restricts the mapping to devices of this manufacturer. Empty/absent = all manufacturers. Matched case-insensitively.

model

string

No

Restricts the mapping to devices of this model. Empty/absent = all models. May be combined with manufacturer. Matched case-insensitively.

attrs

string

No

Reserved. Carried in the snapshot but not evaluated at runtime.

A column entry with no parameter mappings removes all parameter mappings for that column (the column title may be kept because it can still be referenced by the UI). Removing all entries (empty snapshot) removes all mappings: previously created value-change subscriptions are turned off on affected devices (see Reacting to a snapshot change).

5. The activeConnection Attribute

Many account-related parameters (WAN username, WAN MAC address, external IP) live under a WAN connection instance whose index differs from device to device, for example:

InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Username
InternetGatewayDevice.WANDevice.2.WANConnectionDevice.1.WANIPConnection.1.Username

The instance numbers in these paths are different on different devices, so it is impossible to write one fixed path that works for every device. The activeConnection attribute solves this: the ACS tracks, per device, which WAN connection object is currently active, and resolves the mapped parameter relative to it.

5.1. Path resolution

activeConnection=false

The name attribute is used as-is — a complete, absolute parameter path (e.g. Device.ManagementServer.PeriodicInformInterval).

activeConnection=true

The name attribute is a relative suffix. At processing time the ACS prepends the device’s active connection object path to it:

full path = <active connection object> + name

For example, with name="Username" and the active connection object resolved as InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1., the resolved path is:

InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Username

If activeConnection=true but the active connection object has not (yet) been determined for the device, the mapping is skipped for that device and a warning is logged:

Account mapping parameter: <name> has activeConn=true but activeConn undefined for cpe: <serial>

The mapping is applied automatically on a later session once the active connection has been resolved (see below).

5.2. How the active connection object is determined

The active connection is (re)evaluated on every TR-069 Inform and on every GetParameterValuesResponse received from the device:

  1. The ACS reads the device’s ConnectionRequestURL value (the InternetGatewayDevice.ManagementServer.ConnectionRequestURL or Device.ManagementServer.ConnectionRequestURL variant, depending on the data model) and extracts the IP address from it.

  2. The parameters reported in the current message are scanned for a parameter that:

    • contains IPAddress in its name, and

    • has a non-empty value containing that IP address, and

    • belongs to a WAN/IP interface subtree:

      • TR-098 (gateway): path starts with InternetGatewayDevice.WANDevice.

      • TR-181: path starts with Device.IP.Interface. or Device.WANDevice.

  3. The parent object of the matched parameter (the path up to and including the last instance, e.g. InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.) becomes the device’s active connection object.

  4. If the result differs from the previously stored value, it is persisted on the device record (active_conn_name_id column of the cpe table) and the following is logged:

    Updating active connection for cpe: <serial> object: <path>

In other words: the active connection is the WAN interface whose IP address the ACS uses to reach the device for connection requests.

5.3. Behavior when the active connection changes

Mappings with activeConnection=true follow the device:

  • When the active connection object changes (e.g. the device fails over from PPP to IP WAN, or the instance index changes after a reboot), the next processing cycle:

    • subscribes to value changes (active notification, value 2) on the parameter resolved under the new active connection object, and

    • cancels the subscription (notification value 0) on the parameter resolved under the previous active connection object.

  • The current value under the new path is then fetched and written to the mapped cust column, so the column always reflects the active interface.

Mappings with activeConnection=false are unaffected by active-connection changes.

5.4. Behavior on mapping removal

When a parameter mapping with activeConnection=true is removed (or its manufacturer/model scope changes so that devices fall out of scope), the ACS resolves the per-device full path using each affected device’s stored active connection object and turns the value-change notification off for it. For activeConnection=false mappings the same absolute path is used for all affected devices. This off-reconciliation runs when the snapshot change is applied (see Reacting to a snapshot change), not on a device session.

6. Processing Flow

The mapping is evaluated when the ACS receives device data, across all supported protocols:

Protocol Trigger

TR-069 (CWMP)

Inform; GetParameterValues response (asynchronous, time-boxed at 15 s per device)

USP (TR-369)

Device registration; Get task response; notifications

MQTT

Published device data

For a device session the flow is:

  1. The mapping list applicable to the device’s manufacturer/model is loaded from the node’s in-memory near-cache (global mappings plus any scoped to the device’s manufacturer and/or model). No database query is issued for the mappings.

  2. Each parameter is resolved to a full path (see Path resolution); unresolvable entries are skipped.

  3. The resolved path must match the device’s data model root (InternetGatewayDevice., Device. or Root.); mismatching entries are ignored for the device.

  4. For new devices, re-bootstrapped devices, devices whose active connection just changed, or after a mapping change has been applied to this node, the ACS:

    • enables active value-change notification (value 2) on the resolved parameters, and

    • queues a GetParameterValueList pending task for the device to refresh the current values (skipped for LWM2M devices).

  5. The column values are merged into the mapped columns of the cust_device1 table by device serial number, taken from (in order of availability):

    • the parameter values reported by the device in the current session (Inform / GPV response / USP notification / MQTT publish),

    • the values already stored in the cpe_parameter table (merged immediately when subscriptions are applied to an already-known device),

    • the response to the queued GetParameterValueList task, which is processed through the same flow when the device replies.

  6. Since only one of the mapped parameters is expected to exist on a device, normally exactly one value is available per column; if more than one resolves, the first non-empty value wins.

The GetParameterValueList task is not created on every session — only when notification subscriptions are (re)applied (the conditions in step 4). After a snapshot change, an already-known device re-applies its subscriptions once on its next contact, then settles; in the steady state the column values are kept up to date by the active notifications and by values reported in regular sessions, backed by the cpe_parameter table.

7. Troubleshooting

Symptom / log message Cause / action

Account mapping parameter: …​ has activeConn=true but activeConn undefined for cpe: …​

The device’s active connection object has not been resolved yet. Verify the device reports a WAN/IP IPAddress parameter whose value matches the IP in its ConnectionRequestURL. The mapping is applied automatically once resolved.

Updating active connection for cpe: …​ object: …​

Informational — the active connection object was (re)detected for the device.

Custom column stays empty for some devices

Check manufacturer/model scoping on the parameter mappings; check that the parameter path matches the device’s data model (TR-098 vs TR-181); for activeConnection=true entries check active connection resolution.

config-custom-data snapshot missing/unavailable — keeping last-known mappings (degraded)

The ACS could not read the snapshot (Hazelcast unavailable, or ft-configs-service has not published yet). The node keeps its last-known mappings and recovers automatically when the snapshot appears. Verify Hazelcast connectivity and that ft-configs-service has published the config-custom-data snapshot.

Custom columns empty on all devices, no mappings active

The published snapshot is empty (entries=[]) — all mappings were intentionally removed in ft-configs-service — or the snapshot has not been published. Check the mapping configuration in ft-configs-service.

8. Implementation Reference

Class Responsibility

com.friendly.iot.core.customdata.ConfigCustomDataSnapshotConsumer

Consumes the config-custom-data Hazelcast IList, rebuilds the per-node near-cache on each publish, and triggers reconciliation

com.friendly.iot.core.customdata.ConfigCustomDataNearCache / ConfigCustomDataNearCacheHolder

Immutable per-node read model indexed by manufacturer/model (plus a global bucket); the holder publishes the current near-cache via an atomic swap

com.friendly.iot.core.customdata.ConfigCustomDataSnapshotReconciler

Single-owner reconciliation on snapshot change: turns value-change notifications off for removed mappings (diff against the cluster-authoritative previous snapshot)

com.friendly.iot.core.service.ConfigCustomDataProcessor

Runtime evaluation: path resolution (including activeConnection), notification/GPV task creation, cust_device1 merge

com.friendly.tr069.core.util.TR069CpeParameterUtil#checkActiveConnection

Active connection object detection from Inform / GPV response parameters

The legacy com.friendly.iot.core.api.ConfigCustomDataService (file load/save, file watching, DB sync, syncConfigCustomData topic) and the JAXB types / SOAP methods have been removed. ConfigCustomDataDao, ConfigCustomParameterDao and the entities ConfigCustomData / ConfigCustomParameter are deprecated (tables not yet dropped).