pub struct Updater<S> { /* private fields */ }Expand description
Applies the update rules against a device’s slots.
Implementations§
Source§impl<S: SlotStore> Updater<S>
impl<S: SlotStore> Updater<S>
Sourcepub fn with_delegation(self, envelope: &[u8], now: Option<u64>) -> Result<Self>
pub fn with_delegation(self, envelope: &[u8], now: Option<u64>) -> Result<Self>
Adopts a delegation the device already held, after a restart.
A delegation is small and its envelope is self-authenticating, so the simplest place to keep one is wherever the caller already keeps device settings. Hand it back here on the way up.
§Arguments
envelope- the stored delegation envelope.now- seconds since the Unix epoch, orNoneon a device with no clock.
§Returns
The updater, now accepting releases signed by the delegated key.
§Errors
Returns whatever adopt refuses.
Sourcepub fn adopt(&mut self, envelope: &[u8], now: Option<u64>) -> Result<Delegation>
pub fn adopt(&mut self, envelope: &[u8], now: Option<u64>) -> Result<Delegation>
Takes on a delegation, moving which key may sign this device’s updates.
The caller should persist the envelope it just passed, so the device comes back up trusting the same key.
§Arguments
envelope- a delegation signed by the device’s trust anchor.now- seconds since the Unix epoch, orNoneon a device with no clock.
§Returns
The delegation now in force.
§Errors
Returns Refusal::Signature if it was not signed by the trust anchor,
Refusal::Rollback if its epoch does not rise above the one already
held, so a retired key cannot be reinstated by replay, and
Refusal::Expired or Refusal::NoClock on the same terms as a
manifest.
Sourcepub fn delegation(&self) -> Option<Delegation>
pub fn delegation(&self) -> Option<Delegation>
Returns the delegation in force, if the device holds one.
§Returns
The delegation, or None when releases are signed by the anchor itself.
Sourcepub fn installed_sequence(&self) -> Result<u64>
pub fn installed_sequence(&self) -> Result<u64>
Returns the highest sequence number any slot holds.
A new manifest must beat this, not merely the running image, so an older release cannot be slipped in alongside a newer one that is already staged. Failed slots count too: re-releasing a sequence that already failed would let a captured image be replayed.
§Returns
The highest sequence number present, or 0 if every slot is empty.
§Errors
Returns a refusal if a slot record cannot be read.
Sourcepub fn begin(&mut self, envelope: &[u8]) -> Result<Staging<'_, S>>
pub fn begin(&mut self, envelope: &[u8]) -> Result<Staging<'_, S>>
Checks a manifest and opens the slot it names for writing.
§Arguments
envelope- the signed manifest offered to this device.
§Returns
A Staging ready to take the image, once every check that can be made
without the image has passed.
§Errors
Returns whatever begin_at refuses. A manifest that
carries an expiry is refused, because a device with no clock cannot honour
one; call begin_at with the time if it has one.
Sourcepub fn begin_at(
&mut self,
envelope: &[u8],
now: Option<u64>,
) -> Result<Staging<'_, S>>
pub fn begin_at( &mut self, envelope: &[u8], now: Option<u64>, ) -> Result<Staging<'_, S>>
Checks a manifest against the current time and opens the slot it names.
§Arguments
envelope- the signed manifest offered to this device.now- seconds since the Unix epoch, orNoneon a device with no clock.
§Returns
A Staging ready to take the image, once every check that can be made
without the image has passed.
§Errors
Returns Refusal::Signature if the envelope is not from the trusted
author, Refusal::WrongDevice if it is for a different vendor or class,
Refusal::Expired if its expiry has passed, Refusal::NoClock if it
expires and now is None, Refusal::Rollback if it would not move the
device forward, Refusal::SlotTooSmall if the image cannot fit, or
Refusal::WrongState if it names the slot the device would fall back to.
Sourcepub fn resume_at(
&mut self,
envelope: &[u8],
now: Option<u64>,
) -> Result<Staging<'_, S>>
pub fn resume_at( &mut self, envelope: &[u8], now: Option<u64>, ) -> Result<Staging<'_, S>>
Opens a slot for an image, continuing a transfer that was cut off.
A slow radio can spend half an hour on a single image, so a link that drops near the end must not mean starting again. If the slot already holds part of exactly this image, the transfer picks up where it stopped; anything else starts over, because mixing two images produces neither. An image whose last byte arrived but which was never settled counts as picking up where it stopped, so a reset in that gap costs nothing.
§Arguments
envelope- the signed manifest offered to this device.now- seconds since the Unix epoch, orNoneon a device with no clock.
§Returns
A Staging positioned after whatever already arrived, which
progress reports.
§Errors
Returns whatever begin_at refuses.
Sourcepub fn stage(&mut self, envelope: &[u8], image: &[u8]) -> Result<u8>
pub fn stage(&mut self, envelope: &[u8], image: &[u8]) -> Result<u8>
Checks a manifest and stages an image already held whole.
§Arguments
envelope- the signed manifest.image- the whole image.
§Returns
The slot the image was staged into.
§Errors
Returns whatever begin or Staging::finish refuses.
Sourcepub fn stage_at(
&mut self,
envelope: &[u8],
image: &[u8],
now: Option<u64>,
) -> Result<u8>
pub fn stage_at( &mut self, envelope: &[u8], image: &[u8], now: Option<u64>, ) -> Result<u8>
Checks a manifest against the current time and stages an image held whole.
§Arguments
envelope- the signed manifest.image- the whole image.now- seconds since the Unix epoch, orNoneon a device with no clock.
§Returns
The slot the image was staged into.
§Errors
Returns whatever begin_at or Staging::finish
refuses.
Sourcepub fn on_boot(&mut self) -> Result<Boot>
pub fn on_boot(&mut self) -> Result<Boot>
Decides what to run, and records that decision before returning it.
Call this once per boot, before jumping to an image. A staged image becomes pending here, so if the device resets before confirming, the next call sees a pending slot and reverts.
§Returns
What the bootloader should run.
§Errors
Returns Refusal::NothingToRevert if there is no image to fall back to.
Sourcepub fn confirm(&mut self) -> Result<u8>
pub fn confirm(&mut self) -> Result<u8>
Reports the running image healthy, making it the one to fall back to.
The slot the device previously fell back to is erased, which is what frees it to receive the next update.
§Returns
The slot that is now confirmed.
§Errors
Returns Refusal::WrongState if no image is pending, so a confirmation
that arrives twice, or from an image nobody is trying, does nothing.
Sourcepub fn revert(&mut self) -> Result<u8>
pub fn revert(&mut self) -> Result<u8>
Gives up on the pending image and goes back to the confirmed one.
§Returns
The slot the device falls back to.
§Errors
Returns Refusal::WrongState if no image is pending, or
Refusal::NothingToRevert if there is nothing to fall back to.
Sourcepub fn provision(&mut self, slot: u8, sequence: u64) -> Result<()>
pub fn provision(&mut self, slot: u8, sequence: u64) -> Result<()>
Marks a slot confirmed at first provisioning, when nothing was staged.
A device leaves the factory already running an image that no update installed. Without this there is no fallback for the first update to return to.
§Arguments
slot- the slot the factory image occupies.sequence- the sequence number of that image.
§Returns
Ok(()) once the slot is confirmed.
§Errors
Returns Refusal::WrongState if any slot is already confirmed.