Skip to content

Wireless Profile Sync Settings Management Architecture

shaoboon edited this page Jun 10, 2026 · 2 revisions

This document describes the architecture introduced by the wireless profile synchronization feature in Console. It lets an operator read and toggle two independent Intel® AMT wireless synchronization behaviors on a managed device without rewriting the whole WiFi port configuration:

  • Local profile sync — whether the AMT firmware may synchronize WiFi profiles with the local host operating system.
  • UEFI profile sync — whether WiFi profiles are shared with the platform UEFI/BIOS (pre-boot) WiFi stack, subject to hardware capability.

1. High-level architecture

Two systems are involved: Console (the management application) and the AMT Device (the managed endpoint). Console exposes a user-facing REST API on one side and talks to the device over WS-Management (WSMAN) on the other, using the Intel® AMT SDK semantics implemented by the go-wsman-messages library. Both sync toggles are driven through the single AMT_WiFiPortConfigurationService instance on the device.

flowchart LR
    Client[REST client] -->|GET / POST localProfileSync/:guid<br/>GET / POST uefiProfileSync/:guid| ConsoleAPI[Console REST API]
    subgraph Console
        ConsoleAPI --> UseCase[Devices Use Case]
        UseCase --> WSMAN[wsman.Management adapter]
    end
    WSMAN -->|SOAP / XML over HTTPS| Svc
    subgraph Device[Intel® AMT Device]
        Svc[AMT_WiFiPortConfigurationService]
        Caps[AMT_BootCapabilities]
    end
    WSMAN -.UEFI gate.-> Caps
Loading

2. Console interfaces and data

2.1 User-facing API (north-bound)

Console exposes four endpoints for this feature, paired GET/POST per sync target.

Method Path Payload Handler Success response
GET /api/v1/amt/networkSettings/wireless/localProfileSync/:guid N/A getWirelessLocalProfileSync 200 OK + { "enabled": bool }
POST /api/v1/amt/networkSettings/wireless/localProfileSync/:guid WirelessProfileSyncRequest putWirelessLocalProfileSync 200 OK + { "enabled": bool }
GET /api/v1/amt/networkSettings/wireless/uefiProfileSync/:guid N/A getWirelessUEFIProfileSync 200 OK + { "enabled": bool }
POST /api/v1/amt/networkSettings/wireless/uefiProfileSync/:guid WirelessProfileSyncRequest putWirelessUEFIProfileSync 200 OK + { "enabled": bool }

WirelessProfileSyncRequest / WirelessProfileSyncResponse fields:

Field (JSON) Type Binding tag Validation note
enabled (request) *bool required Mandatory. A custom UnmarshalJSON rejects a missing or null enabled with ErrProfileSyncEnabledRequired, returned as 400 Bad Request.
enabled (response) bool The effective state after the operation, re-read from the device.

The request type carries a pointer (*bool) so Console can distinguish "field absent" from false. The BoolValue() helper safely dereferences it (returns false when nil) before passing the desired state into the use case.

2.2 Device interface (south-bound) — Intel AMT SDK

Console talks to the device through the wsman.Management interface in internal/usecase/devices/wsman/interfaces.go, implemented by ConnectionEntry in internal/usecase/devices/wsman/message.go. Each method is a thin wrapper over a go-wsman-messages call. The operations relevant to this feature:

Method Purpose SDK / class
GetWiFiPorts() enumerate/pull WiFi ports; returns ErrNoWiFiPort when none exist CIM_WiFiPort
GetWiFiPortConfigurationService() read the current WiFi port configuration service state AMT_WiFiPortConfigurationService.Get
PutWiFiPortConfigurationService(req) overwrite the WiFi port configuration service with a full request AMT_WiFiPortConfigurationService.Put
GetPowerCapabilities() read boot capabilities; used to gate UEFI sync AMT_BootCapabilities

The Put requires a complete wifiportconfiguration.WiFiPortConfigurationServiceRequest. The use case never builds one from scratch: buildWiFiPortConfigRequest copies every field verbatim from the current WiFiPortConfigurationServiceResponse and overlays only the two sync-related fields, so unrelated firmware state is not clobbered.

AMT SDK request field Source
RequestedState, EnabledState, HealthState, ElementName Copied from current settings
SystemCreationClassName, SystemName, CreationClassName, Name Copied from current settings
LastConnectedSsidUnderMeControl, NoHostCsmeSoftwarePolicy Copied from current settings
LocalProfileSynchronizationEnabled Local-sync flow → resolved sync state; UEFI flow → copied from current settings
UEFIWiFiProfileShareEnabled UEFI flow → resolved effective state; local-sync flow → copied from current settings

The local sync field is an enum, not a boolean. The use case maps between the REST boolean and the SDK enum:

Console boolean LocalProfileSynchronizationEnabled enum
true LocalUserProfileSynchronizationEnabled (1)
false LocalSyncDisabled (0)

isLocalProfileSyncEnabled performs the reverse mapping (true only when the state equals LocalUserProfileSynchronizationEnabled). The UEFI field (UEFIWiFiProfileShareEnabled) is already a boolean and maps directly.

3. Business logic layer (Devices Use Case)

Implemented in internal/usecase/devices/wifiprofilesync.go. All four use-case methods begin the same way: setupWirelessProfileManagement (shared with WiFi profile management) loads the device by GUID and opens a WSMAN client, then GetWiFiPorts() asserts the device actually has a WiFi interface — returning ErrNoWiFiPort (→ 404 Not Found) otherwise — before any configuration read or write.

GET flow — GetWirelessLocalProfileSync / GetWirelessUEFIProfileSync read the current WiFiPortConfigurationService and project out the single relevant field:

sequenceDiagram
    participant C as REST client
    participant API as Console API
    participant UC as Devices Use Case
    participant W as wsman.Management
    participant D as AMT Device

    C->>API: GET localProfileSync/:guid (or uefiProfileSync)
    API->>UC: GetWirelessLocalProfileSync(guid)
    UC->>W: setup client + GetWiFiPorts()
    W->>D: Enumerate + Pull CIM_WiFiPort
    alt no WiFi interface
        W-->>UC: ErrNoWiFiPort
        UC-->>API: ErrNoWiFiPort
        API-->>C: 404 Not Found
    else WiFi interface present
        UC->>W: GetWiFiPortConfigurationService()
        W->>D: AMT_WiFiPortConfigurationService.Get
        D-->>W: service state
        UC-->>API: enabled (bool)
        API-->>C: 200 OK + { "enabled": bool }
    end
Loading

POST flow (local sync) — PutWirelessLocalProfileSync reads current state, compares it to the requested value, and only issues a Put when they differ (read-before-write). When no change is needed it returns the current value without touching the device:

sequenceDiagram
    participant C as REST client
    participant API as Console API
    participant UC as Devices Use Case
    participant W as wsman.Management
    participant D as AMT Device

    C->>API: POST localProfileSync/:guid { "enabled": true }
    API->>UC: PutWirelessLocalProfileSync(guid, true)
    UC->>W: setup client + GetWiFiPorts()
    UC->>W: GetWiFiPortConfigurationService()
    W->>D: AMT_WiFiPortConfigurationService.Get
    D-->>W: current state
    UC->>UC: map bool -> LocalProfileSynchronizationEnabled enum
    alt current == requested
        UC-->>API: current value (no write)
    else current != requested
        UC->>UC: buildWiFiPortConfigRequest(current, newSync, current UEFI)
        UC->>W: PutWiFiPortConfigurationService(req)
        W->>D: AMT_WiFiPortConfigurationService.Put
        D-->>W: updated state
        UC-->>API: updated value
    end
    API-->>C: 200 OK + { "enabled": bool }
Loading

POST flow (UEFI sync) — PutWirelessUEFIProfileSync adds a capability gate. When the caller requests enable, the use case reads GetPowerCapabilities() and uses the device's UEFIWiFiCoExistenceAndProfileShare capability as the effective target. On hardware that does not support pre-boot WiFi sharing this capability is false, so an enable request resolves to false and no write occurs — unsupported hardware can never be turned on. Disable requests skip the capability read:

sequenceDiagram
    participant C as REST client
    participant API as Console API
    participant UC as Devices Use Case
    participant W as wsman.Management
    participant D as AMT Device

    C->>API: POST uefiProfileSync/:guid { "enabled": true }
    API->>UC: PutWirelessUEFIProfileSync(guid, true)
    UC->>W: setup client + GetWiFiPorts()
    UC->>W: GetWiFiPortConfigurationService()
    W->>D: AMT_WiFiPortConfigurationService.Get
    D-->>W: current state
    opt enable requested
        UC->>W: GetPowerCapabilities()
        W->>D: AMT_BootCapabilities
        D-->>W: UEFIWiFiCoExistenceAndProfileShare
        UC->>UC: effective = capability value
    end
    alt current == effective
        UC-->>API: current value (no write)
    else current != effective
        UC->>UC: buildWiFiPortConfigRequest(current, current sync, effective UEFI)
        UC->>W: PutWiFiPortConfigurationService(req)
        W->>D: AMT_WiFiPortConfigurationService.Put
        D-->>W: updated state
        UC-->>API: updated value
    end
    API-->>C: 200 OK + { "enabled": bool }
Loading

Other behaviors:

  • No WiFi interface — every flow surfaces wsman.ErrNoWiFiPort; the handlers in internal/controller/httpapi/v1/wifiprofilesync.go translate it to 404 Not Found with a descriptive message, while all other errors fall through to the shared ErrorResponse mapping.
  • Invalid payload — a missing/null enabled field is rejected at bind time (ShouldBindJSON → custom UnmarshalJSON) and returned as 400 Bad Request.
  • Idempotent writes — the read-before-write check means repeating a POST with an already-applied value performs a Get only, leaving the device untouched and returning the current state.
  • Independent fields — toggling local sync preserves the current UEFI value and vice versa, because buildWiFiPortConfigRequest carries the untouched field through from the current settings.

4. Key files

Area File
HTTP handlers internal/controller/httpapi/v1/wifiprofilesync.go
Route registration internal/controller/httpapi/v1/devicemanagement.go
OpenAPI / Fuego declaration internal/controller/openapi/devicemanagement.go
DTOs (request/response) internal/entity/dto/v1/wifiprofilesync.go
Use case (business logic) internal/usecase/devices/wifiprofilesync.go
Shared WSMAN setup helper internal/usecase/devices/wifiprofile.go
WS layer interface internal/controller/ws/v1/interface.go
Use case interface internal/usecase/devices/interfaces.go
WSMAN interface internal/usecase/devices/wsman/interfaces.go
WSMAN adapter (SDK calls) internal/usecase/devices/wsman/message.go
AMT SDK dependency go-wsman-messages/v2 — amt/wifiportconfiguration, amt/boot
API collection MPS Postman collection (console_mps_apis.postman_collection.json)
Handler tests internal/controller/httpapi/v1/wifiprofilesync_test.go
DTO tests internal/entity/dto/v1/wifiprofilesync_test.go
Use case tests internal/usecase/devices/wifiprofilesync_test.go

Clone this wiki locally