# Implemented device-agent integration contract

Implementation checkpoint: 26 September 2026. This contract applies to Android UIC Home and Linux A10-T xTMSAgent. See chapter 33 and the bilingual platform manuals for installation and acceptance.

## Identity and onboarding

1. A SuperAdmin onboards the exact manufacturer serial under one customer and one portal model.
2. The agent receives or claims a unique device ID, assignment epoch, Device Secret and topic prefix. A device cannot create its own portal record.
3. The agent creates a private key locally, requests an IoT certificate, confirms possession and connects with mutual TLS.
4. The first MQTT admission that validates certificate, Device Secret, assignment and topic scope marks the device IoT Provisioned and closes further enrollment downloads.

Android test/debug enrollment is transferred to private app storage and encrypted with AndroidKeyStore. Linux xTMSAgent claims the already-onboarded serial from a protected customer bootstrap, stores enrollment as mode `0600` and removes the bootstrap file. Neither flow embeds a reusable terminal Device Secret in source or a fleet-wide APK/package.

## Transport

Production defaults are HTTPS/WSS 5102 and MQTTS 5883. Development defaults are HTTPS 15102 and MQTTS 18883. Validate the server hostname and certificate; do not disable TLS checks.

MQTT identity is the canonical device UUID, not the human serial. Client ID and username are the device ID; password is the unique Device Secret; the client certificate fingerprint must be bound to that same device and assignment.

| Direction | Topic |
| --- | --- |
| Device publishes | `uic/tms/v1/devices/{deviceId}/telemetry` |
| Device publishes | `uic/tms/v1/devices/{deviceId}/results` |
| Device publishes | `uic/tms/v1/devices/{deviceId}/config/request` |
| Device subscribes | `uic/tms/v1/devices/{deviceId}/commands` |
| Device subscribes | `uic/tms/v1/devices/{deviceId}/receipts` |
| Device subscribes | `uic/tms/v1/devices/{deviceId}/config/response` |

Wildcard and foreign-device access is denied. Use QoS 1, non-retained messages and bounded payloads. HTTPS carries application/parameter artifacts; WSS carries Android remote frames/input. MQTT does not carry APKs, native packages or screen frames.

## Envelope and storage receipt

```json
{
  "protocolVersion": 1,
  "messageId": "33333333-3333-4333-8333-333333333333",
  "deviceId": "11111111-1111-4111-8111-111111111111",
  "assignmentEpoch": 1,
  "sentAtUtc": "2026-09-26T18:00:00Z",
  "payload": {}
}
```

Persist the exact serialized envelope before publish. Remove it only after a matching receipt such as:

```json
{"protocolVersion":1,"messageId":"33333333-3333-4333-8333-333333333333","stored":true,"duplicate":false}
```

MQTT PUBACK is not database confirmation. After reconnect or a missing receipt, resend the same bytes and message ID. A duplicate with the same hash receives `duplicate:true`; reuse with different content is rejected.

## Telemetry payload

Agents report the latest snapshot, including:

- agent version/package, manufacturer serial, brand, portal model family and complete reported model;
- OS name/version/API when available, uptime and boot evidence;
- battery/charging on supported Android devices;
- free and total storage, available and total memory;
- connection type, local interface IP/MAC, IMEI/ICCID where permitted and public IP observed by TMS;
- capabilities and bounded user-application inventory;
- optional location with latitude, longitude, accuracy and source.

Android inventory excludes system applications/updates. Linux A10 inventory uses `userappl/cfg/appname.txt`, `version.txt` and the configured application ID. Do not replay old snapshots after a newer one; the portal presents received freshness, not the device clock as authority.

Location history records a new point after at least 100 metres. A device-reported valid point overrides manual portal location. See chapter 34.

## Commands and results

```json
{
  "protocolVersion": 1,
  "commandId": "22222222-2222-4222-8222-222222222222",
  "deviceId": "11111111-1111-4111-8111-111111111111",
  "assignmentEpoch": 1,
  "type": "report_status",
  "payload": {},
  "expiresAtUtc": "2026-09-26T18:05:00Z"
}
```

Validate protocol, device, assignment, type and expiry. Persist the command ID before an external effect. Redelivery returns the stored result and must not repeat message display, reboot or installation. Unknown or expired commands fail safely.

```json
{
  "commandId":"22222222-2222-4222-8222-222222222222",
  "state":"Succeeded",
  "detail":"Status stored"
}
```

Results use a new envelope message ID and remain in the durable outbox until a storage receipt arrives. The server validates operation-specific evidence: a fresh status receipt, a new boot/uptime state, matching package/version/hash after install, or package absence after uninstall. Dispatch never counts as success.

Implemented common command types include `report_status`, `send_message`, `reboot`, `install_application`/`install_zip`, `uninstall_application` and parameter/configuration request paths. Android additionally supports remote assistance; Linux uses a payment-app file bridge and has no remote desktop.

## Application delivery

The command supplies an authenticated HTTPS download URL, package identity, version, expected size/hash and model compatibility. The agent downloads to temporary storage, enforces bounds, validates SHA-256 and uses its platform installer.

Android verifies package ID, version, signer and installed APK hash, then invokes the NEWPOS or NEXGO SDK. UIC Home cannot remotely uninstall itself, the active Home application or system packages.

Linux A10 accepts the native signed `prodapp.tarball.tar.gz`. The portal validates archive structure/hash; xTMSAgent checks the command hash and invokes `os_update_application`, whose vendor path verifies the A10 signature. Successful A10 install/uninstall reports evidence before reboot and publishes new inventory afterward.

## Parameters

The agent sends an application-scoped request with the last applied configuration hash. TMS compiles current saved schema/catalog/device values on demand and returns either `upToDate:true` or the current JSON payload/hash.

Android exposes the result through UIC Home's read-only payment-app provider. Linux writes it to the configured parameter payload and bridge response files. Neither agent should reapply an unchanged hash. The server currently has no independent app-applied receipt or scheduled parameter push.

## Security and restrictions

- Never transmit full PAN, track data, CVV, PIN data, payment keys, Device Secrets, bootstrap keys or private keys in telemetry/results/logs.
- Enforce payload size/depth/collection limits and sanitize displayed text.
- Preserve enrollment/keys across ordinary updates; loss requires approved recovery and IoT rotation.
- Rotation revokes prior certificates. Revocation blocks MQTT and new issuance until an explicit rotation reopens provisioning.
- Android screen-off reliability requires foreground service plus battery-policy qualification. USB reverse is lab-only.
- A10 communications configuration must work before enrollment; otherwise a new terminal cannot reach TMS.
- A10 production installation steps remain pending; the lab update script is not the enrollment mechanism.

