Radio Silence Implementation
Radio silence is the act of disabling all radio transmission for safety or security reasons. To learn more about this feature in terms of use-cases, design decisions, terminology and APIs, please refer to the user-facing EVE documentation, section WIRELESS.
Radio silence implementation is split between 3 EVE microservices:
zedagent: If Local profile server is deployed and running, the microservice makes a POST request to the Radio endpoint every 5 seconds. In the request body, it publishes the current state of all used wireless devices, which it obtains from theDeviceNetworkStatus(DNSfor short; the message is received from NIM). Radio silence status in encapsulated byRadioSilencestructure, embedded intoDNS. It contains aChangeInProgressboolean, which NIM (specifically DPCManager component) uses to inform that an operation of switching radio silence ON/OFF is still in progress and that zedagent should therefore pause Radio endpoint POST requests until it finalizes.
Whenever the Local profile server responds with a radio silence configuration that differs from
the current state, zedagent will record the new intended radio state into RadioSilence structure
embedded into ZedAgentStatus. zedagent will also record the time of the request in RadioSilence.ChangeRequestedAt.
NIM should then copy this timestamp to DeviceNetworkStatus.RadioSilence to match the request with the
corresponding state update (see below).
When zedagent sees DeviceNetworkStatus with RadioSilence where ChangeRequestedAt equals
the last configuration request time and ChangeInProgress has changed to false, it knows
that the operation has finalized and it can publish the status up to the Local profile server.
NIM: ReceivesZedAgentStatuswith the intended radio silence state. With each new publication ofZedAgentStatus, it first checks ifRadioSilence.ChangeRequestedAtis greater than the timestamp of the last seen radio configuration change. If it is the case, it copiesChangeRequestedAtfromZedAgentStatus.RadioSilencetoDeviceNetworkStatus.RadioSilence, setsChangeInProgresstotrueand starts switching radios of wireless devices ON/OFF. For WiFi adapters, this is done by directly calling the rfkill command. For cellular modems, NIM updates and publishes newWwanConfigvia pubsub, which is received bymmagentof thewwanmicroservice. NIM then waits for the status update fromwwanpublished through pubsub topicWwanStatus. To avoid NIM processing obsoleteWwanStatus, corresponding to an olderWwanConfigand thus not reflecting the latest radio config,ChangeRequestedAtfrom the radio config is appended toWwanConfigby NIM (as well as DPC key + timestamp), which is copied toWwanStatusbymmagentonly once this config has been fully applied. Using this mechanism, NIM is able to ignore obsolete wwan status updates.
Once NIM is done with all radio devices, it updates RadioSilence of DeviceNetworkStatus and sets
ChangeInProgress to false and Imposed (boolean) to reflect the actual radio silence state
(could be different from the intended state if operation failed for any of the wireless devices).
If the operation fails, it also shares all error messages with zedagent, to be published up
to the Local profile server.
wwan: Microservice running ModemManager, controlling WWAN (2G/3G/4G/5G) devices and connections, and mmagent, a Go program build on top of the pillar infrastructure (pubsub, agentbase, logging, etc.), acting as a translation layer between declarative EVE cellular API and imperative ModemManager API. More information about this microservice can be found in WIRELESS.md. What is important here, is that the input (i.e. wwan config) is received by mmagent from NIM via pubsub asWwanConfig. A boolean fieldRadioSilenceis used to order the microservice to either enable or disable radio transmission on all cellular modems visible to the host. mmagent uses SetPowerState method of the DBus-based ModemManager API. It setsMM_MODEM_POWER_STATE_LOWfor a given modem if radio silence is enabled or if the modem is not managed, i.e. it is not configured by the controller. Otherwise,MM_MODEM_POWER_STATE_ONis set to enable radio transmission functions. State updates (including the actual state of radio transmission) are published asWwanStatus. Included is identification of the last applied configuration. This consists of several fields that NIM appends toWwanConfig, referencing the sources of the configuration (DPC key+timestamp, RadioSilence timestamp), which are then simply copied toWwanStatusbywwanmicroservice when the config is fully applied. This allows NIM to wait for a config update to be fully processed, without any operations still ongoing, and to prepare and publish DeviceNetworkStatus that correctly reflects the new config. Having sources ofWwanConfigidentified also helps with debugging. For a givenWwanConfig, it is possible to go backwards in logs and trace the origins of the corresponding DPC and RadioSilence config thatWwanConfigwas generated from.
To summarize, the indented radio configuration flow is:
Local profile server --POST-response--> zedagent --ZedAgentStatus--> NIM --WwanConfig--> wwan (mmagent --SetPowerState--> ModemManager)
--> rfkill ((un)block wlan)
And the status update flow is:
wwan (ModemManager --(Get)PowerState--> mmagent) --WwanStatus--> NIM --DeviceNetworkStatus--> zedagent --POST-request--> Local profile server
rfkill exit status -->