Class Updater
A device's slots, and the rules applied to what is offered for them.
public sealed class Updater : IDisposable
- Inheritance
-
Updater
- Implements
- Inherited Members
Remarks
A device that cannot be fixed in the field is a device that has to be visited, and some of them are a day's travel away. A release carries a manifest naming who it is for and what it hashes to, a device refuses anything not signed by the key it trusts, and an image that fails to confirm itself is rolled back to the one that worked.
Constructors
Updater(ReadOnlySpan<byte>, ReadOnlySpan<byte>, ReadOnlySpan<byte>, byte, uint)
Creates an updater for a device with a number of slots.
public Updater(ReadOnlySpan<byte> vendorId, ReadOnlySpan<byte> classId, ReadOnlySpan<byte> anchorPublicKey, byte slotCount, uint slotCapacity)
Parameters
vendorIdReadOnlySpan<byte>Who built this firmware, as 16 bytes.
classIdReadOnlySpan<byte>What kind of device this is, as 16 bytes.
anchorPublicKeyReadOnlySpan<byte>The 32-byte key this device anchors its trust in, which is the root of every decision about who may update it.
slotCountbyteHow many slots the device has.
slotCapacityuintHow many bytes each slot holds.
Exceptions
- PamojaException
The native updater could not be created.
Properties
CurrentDelegation
Gets the delegation this updater honours, or null when releases must
be signed by the anchor itself.
public Delegation? CurrentDelegation { get; }
Property Value
InstalledSequence
Gets the highest sequence number the device already holds.
public ulong InstalledSequence { get; }
Property Value
Exceptions
- PamojaException
The native call failed.
SlotCount
Gets how many slots this device has.
public byte SlotCount { get; }
Property Value
Methods
Adopt(ReadOnlySpan<byte>, ulong?)
Adopts a delegation, accepting releases signed by the key it names.
public Delegation Adopt(ReadOnlySpan<byte> envelope, ulong? now = null)
Parameters
envelopeReadOnlySpan<byte>The signed delegation envelope.
nowulong?Seconds since the Unix epoch, or
nullon a device with no clock.
Returns
- Delegation
The adopted delegation.
Exceptions
- PamojaException
The delegation is not from the anchor, is not newer than the one held, or has expired.
Begin(ReadOnlySpan<byte>, ulong?)
Checks a manifest and opens its slot for a transfer in pieces.
public byte Begin(ReadOnlySpan<byte> envelope, ulong? now = null)
Parameters
envelopeReadOnlySpan<byte>The signed manifest offered to this device.
nowulong?Seconds since the Unix epoch, or
nullon a device with no clock.
Returns
- byte
The slot the image will be written into.
Remarks
Every check that can be made without the image runs here, so a release that is not for this device, would roll it back, or does not fit is refused before a byte of it is accepted. The envelope is remembered until Finish(), and each call after this one reopens the transfer from what the slot records, which is the same path a device takes after a reset.
Exceptions
- PamojaException
A rule refused the update.
Confirm()
Confirms the pending image, so it will be run from now on.
public byte Confirm()
Returns
- byte
The slot that is now confirmed.
Exceptions
- PamojaException
There is no pending image.
CurrentProgress()
Reports how much of an opened image has arrived.
public Progress CurrentProgress()
Returns
- Progress
The bytes stored so far and the total the manifest declares.
Exceptions
- PamojaException
No transfer is open.
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
Finish()
Finishes an opened image, marking the slot bootable if it matched.
public byte Finish()
Returns
- byte
The slot now holding a staged image.
Exceptions
- PamojaException
No transfer is open, or the image is not the one the manifest described, which leaves the slot unbootable.
OnBoot()
Decides what to run, recording the decision before returning it.
public BootDecision OnBoot()
Returns
- BootDecision
What the bootloader should do.
Remarks
Call this once per boot, before jumping to an image. A staged image becomes pending here, so a device that resets before confirming reverts on the next call rather than trying a broken image forever.
Exceptions
- PamojaException
There is nothing to fall back to.
Provision(byte, ulong)
Records that a slot holds a confirmed image at a sequence number.
public void Provision(byte slot, ulong sequence)
Parameters
Remarks
This is how a device that shipped with firmware says what it is running, so the rollback rule has something to compare against.
Exceptions
- PamojaException
The native call failed.
Record(byte)
Reads what the device believes about one slot.
public SlotRecord Record(byte slot)
Parameters
slotbyteThe slot to read.
Returns
- SlotRecord
The record.
Exceptions
- PamojaException
The device has no such slot.
Revert()
Fails the pending image and goes back to the confirmed one.
public byte Revert()
Returns
- byte
The slot to fall back to.
Exceptions
- PamojaException
There is nothing to fall back to.
Stage(ReadOnlySpan<byte>, ReadOnlySpan<byte>, ulong?)
Checks a manifest and stages an image that is already held whole.
public byte Stage(ReadOnlySpan<byte> envelope, ReadOnlySpan<byte> image, ulong? now = null)
Parameters
envelopeReadOnlySpan<byte>The signed manifest offered to this device.
imageReadOnlySpan<byte>The whole image.
nowulong?Seconds since the Unix epoch, or
nullon a device with no clock.
Returns
- byte
The slot the image was staged into.
Exceptions
- PamojaException
A rule refused the update.
Write(ReadOnlySpan<byte>)
Takes the next piece of an image opened with Begin(ReadOnlySpan<byte>, ulong?).
public void Write(ReadOnlySpan<byte> chunk)
Parameters
chunkReadOnlySpan<byte>The next bytes of the image, in order.
Exceptions
- PamojaException
No transfer is open, or more bytes arrived than the manifest declared.