Table of Contents

Class Updater

Namespace
Pamoja.Update
Assembly
Pamoja.Update.dll

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

vendorId ReadOnlySpan<byte>

Who built this firmware, as 16 bytes.

classId ReadOnlySpan<byte>

What kind of device this is, as 16 bytes.

anchorPublicKey ReadOnlySpan<byte>

The 32-byte key this device anchors its trust in, which is the root of every decision about who may update it.

slotCount byte

How many slots the device has.

slotCapacity uint

How 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

Delegation

InstalledSequence

Gets the highest sequence number the device already holds.

public ulong InstalledSequence { get; }

Property Value

ulong

Exceptions

PamojaException

The native call failed.

SlotCount

Gets how many slots this device has.

public byte SlotCount { get; }

Property Value

byte

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

envelope ReadOnlySpan<byte>

The signed delegation envelope.

now ulong?

Seconds since the Unix epoch, or null on 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

envelope ReadOnlySpan<byte>

The signed manifest offered to this device.

now ulong?

Seconds since the Unix epoch, or null on 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

slot byte

The slot holding the running image.

sequence ulong

The sequence number of that image.

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

slot byte

The 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

envelope ReadOnlySpan<byte>

The signed manifest offered to this device.

image ReadOnlySpan<byte>

The whole image.

now ulong?

Seconds since the Unix epoch, or null on 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

chunk ReadOnlySpan<byte>

The next bytes of the image, in order.

Exceptions

PamojaException

No transfer is open, or more bytes arrived than the manifest declared.