pub type ReinitializeHandler = Arc<dyn Fn(&ReinitializeContext, &mut ObjectDatabase) -> Result<(), Error> + Send + Sync>;Expand description
Carries out a ReinitializeDevice request (Clause 16.4) on a full server or an endpoint session.
It is called only for a request that decoded, passed its password check
and names a state the clause defines. Ok(()) sends the SimpleACK; an
Err is sent in its place. The rules:
- Reply first, restart later. The SimpleACK goes out only after the handler returns, so it must not restart the device inline. Accept or refuse, prepare, and schedule the restart (or the backup or restore step) to run after the reply: Clause 16.4.2 has the device acknowledge the request before it shuts down.
- No reply signal yet. Nothing tells the application when the
SimpleACK has left (#1565), so any delay before restarting is best
effort, and on MS/TP it can need longer: a postponed reply waits for
the token.
BACnetServer::stopseals responses and aborts request tasks before joining them, so a restart path that stops the server before the reply has left drops the SimpleACK. On a full server, accepted WARMSTART/COLDSTART ends DISABLE_INITIATION immediately (Clause 16.1.2), cancels its timer and resumes held COV, even if the reply later fails. - Be quick. It runs synchronously on a runtime worker with the object database write-locked, so every other request waits for it. Hand slow work, such as writing backup files, to a task. On an endpoint session a blocking handler stalls the whole session.
- Database edits are raw. On a full server, changes made through the
&mut ObjectDatabaseskip whatBACnetServer::write_localadds around a write: the Object_Name uniqueness check, the COV fanout, the event pass, Schedule and Command follow-ups, and the Audit record. A change that needs them, as ACTIVATE_CHANGES work on Network Port or Device properties may, belongs inwrite_local, called after the reply from a task the handler schedules (for example by sending the change to the code that holds the server). - Gate the requester. Without
reinit_passwordany peer reaches the handler.MutationPolicyand the mutation authorizer don’t cover ReinitializeDevice, so check theReinitializeContextto restrict sources. - Refuse with
Error::Protocol. Its class and code go back in an Error PDU, for example DEVICE / CONFIGURATION_IN_PROGRESS (Clause 16.4.1.3.1). Once the handler has run, the request may no longer be rejected (Clause 20.1.8), so anError::Reject, or any error other thanProtocolorStructured, is sent as SERVICES / OTHER. A panic is caught (with unwind builds) and also answered SERVICES / OTHER, since the handler may have partly acted.
Aliased Type§
pub struct ReinitializeHandler { /* private fields */ }