Table of Contents

Class LorawanRelayNode

Namespace
Pamoja.Lorawan
Assembly
Pamoja.Lorawan.dll

A LoRaWAN relay: an end device that also carries the uplinks of the devices around it.

public sealed class LorawanRelayNode : IDisposable
Inheritance
LorawanRelayNode
Implements
Inherited Members

Remarks

A relay sleeps, waking every scan period to look for radio activity on its wake-on-radio channel. One turn runs like this: NextScan(ulong) says when and where to listen, a frame heard there goes to HeardWor(LorawanScan, ReadOnlySpan<byte>, short, sbyte, ulong), the uplink it announced to HeardUplink(ReadOnlySpan<byte>, short, sbyte, ulong), and Forward(ulong) wraps that in one of the relay's own uplinks on port 226. What the relay's own receive windows hear goes to HeardIn(LorawanReceiveWindow, ReadOnlySpan<byte>, sbyte), which turns a downlink meant for an end device into one to send in that device's relay window.

It owns no radio and no clock, so the same relay runs over any radio, or in a test with none. The codecs behind it are on LorawanRelay.

Properties

DataRate

The data rate the relay forwards at, which its acknowledgments report.

public byte DataRate { get; }

Property Value

byte

DevAddr

The address the relay's own device is on the network by, or null before joining.

public uint? DevAddr { get; }

Property Value

uint?

ForwardDue

When the forwarded uplink waiting to go out is due, or null with none waiting.

public ulong? ForwardDue { get; }

Property Value

ulong?

Joined

Whether the relay's own device is on a network.

public bool Joined { get; }

Property Value

bool

Running

Whether the relay is scanning.

public bool Running { get; }

Property Value

bool

Methods

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()

Forward(ulong)

Sends the uplink the relay is holding, in one of its own on port 226.

public LorawanTransmission Forward(ulong nowMicros)

Parameters

nowMicros ulong

The time, in microseconds.

Returns

LorawanTransmission

What to transmit, with the relay's own receive windows.

Exceptions

LorawanRelayException

Nothing is waiting to go out, or the relay's own device cannot send it yet.

HeardIn(LorawanReceiveWindow, ReadOnlySpan<byte>, sbyte)

Reads a frame the relay's own device heard, acting on the relay commands in it.

public LorawanRelayHeard HeardIn(LorawanReceiveWindow window, ReadOnlySpan<byte> frame, sbyte snrDb)

Parameters

window LorawanReceiveWindow

The window the radio heard it in.

frame ReadOnlySpan<byte>

The bytes the radio received.

snrDb sbyte

Its signal-to-noise ratio.

Returns

LorawanRelayHeard

What it turned out to be: the relay's own downlink, one to pass on to an end device, or one that cannot be passed on.

Exceptions

LorawanRelayException

As Heard(ReadOnlySpan<byte>, sbyte, LorawanReceiveWindow?).

Reads the uplink a wake-on-radio frame announced, and holds it to forward.

public ulong HeardUplink(ReadOnlySpan<byte> frame, short rssiDbm, sbyte snrDb, ulong endedMicros)

Parameters

frame ReadOnlySpan<byte>

The bytes the radio received.

rssiDbm short

Its received signal strength.

snrDb sbyte

Its signal-to-noise ratio.

endedMicros ulong

When the frame ended, in microseconds.

Returns

ulong

When to Forward(ulong) it: fifty milliseconds after it ended.

Exceptions

LorawanRelayException

Nothing announced it, or the frame is not the one it announced.

HeardWor(LorawanScan, ReadOnlySpan<byte>, short, sbyte, ulong)

Reads a wake-on-radio frame a scan heard.

public LorawanWake HeardWor(LorawanScan scan, ReadOnlySpan<byte> frame, short rssiDbm, sbyte snrDb, ulong endedMicros)

Parameters

scan LorawanScan

The scan that heard it, as NextScan(ulong) returned it.

frame ReadOnlySpan<byte>

The bytes the radio received.

rssiDbm short

Its received signal strength, which the forwarded uplink carries.

snrDb sbyte

Its signal-to-noise ratio, which the forwarded uplink carries.

endedMicros ulong

When the frame ended, in microseconds.

Returns

LorawanWake

What the frame led to.

Exceptions

LorawanRelayException

The frame does not verify, the relay does not forward for that device, or a limit is spent.

Join(ushort, ulong)

Makes the relay's own join request.

public LorawanTransmission Join(ushort devNonce, ulong nowMicros)

Parameters

devNonce ushort

A nonce this relay has never used with its join EUI.

nowMicros ulong

The time, in microseconds.

Returns

LorawanTransmission

What to transmit, with the join accept windows.

Exceptions

LorawanRelayException

No credentials, busy, or a wait for the air.

NextScan(ulong)

Says when and where to scan next.

public LorawanScan? NextScan(ulong nowMicros)

Parameters

nowMicros ulong

The time, in microseconds.

Returns

LorawanScan

The scan, or null while the relay is stopped.

NothingHeard(ulong)

Says what comes next once the relay's own windows closed with nothing in them.

public LorawanNext NothingHeard(ulong nowMicros)

Parameters

nowMicros ulong

The time the second window closed, in microseconds.

Returns

LorawanNext

Whether to repeat the frame, join again, or move on.

Exceptions

LorawanRelayException

No transmission waits on its windows.

OverTheAir(LoraChannelPlan, LorawanDevice, LorawanDeviceSettings, LorawanXtalAccuracy, LorawanCadToRx)

Makes a relay whose own device joins over the air.

public static LorawanRelayNode OverTheAir(LoraChannelPlan plan, LorawanDevice credentials, LorawanDeviceSettings settings, LorawanXtalAccuracy xtalAccuracy = LorawanXtalAccuracy.Ppm40, LorawanCadToRx cadToRx = LorawanCadToRx.Symbols8)

Parameters

plan LoraChannelPlan

A published channel plan.

credentials LorawanDevice

The relay's identifiers and root key.

settings LorawanDeviceSettings

What its radio can do.

xtalAccuracy LorawanXtalAccuracy

How accurate its crystal is.

cadToRx LorawanCadToRx

How long it takes to start receiving once it detects activity.

Returns

LorawanRelayNode

The relay, neither joined nor scanning.

Exceptions

PamojaException

The plan was built rather than published.

Personalized(LoraChannelPlan, LorawanSession, LorawanDeviceSettings, LorawanXtalAccuracy, LorawanCadToRx)

Makes a relay whose own device is activated by personalization.

public static LorawanRelayNode Personalized(LoraChannelPlan plan, LorawanSession session, LorawanDeviceSettings settings, LorawanXtalAccuracy xtalAccuracy = LorawanXtalAccuracy.Ppm40, LorawanCadToRx cadToRx = LorawanCadToRx.Symbols8)

Parameters

plan LoraChannelPlan

A published channel plan.

session LorawanSession

The address and session keys the relay was provisioned with.

settings LorawanDeviceSettings

What its radio can do.

xtalAccuracy LorawanXtalAccuracy

How accurate its crystal is, which its acknowledgments report.

cadToRx LorawanCadToRx

How long it takes to start receiving once it detects activity.

Returns

LorawanRelayNode

The relay, stopped until Start(LorawanCadPeriodicity, byte, LoraRelayChannel?).

Exceptions

PamojaException

The plan was built rather than published.

Send(byte, ReadOnlySpan<byte>, ulong, bool)

Sends one of the relay's own uplinks, which also carries what it owes its network.

public LorawanTransmission Send(byte port, ReadOnlySpan<byte> payload, ulong nowMicros, bool confirmed = false)

Parameters

port byte

The application port, 1 to 223.

payload ReadOnlySpan<byte>

The application payload.

nowMicros ulong

The time, in microseconds.

confirmed bool

Whether to ask the network to acknowledge it.

Returns

LorawanTransmission

What to transmit, with its receive windows.

Exceptions

LorawanRelayException

As Send(byte, ReadOnlySpan<byte>, ulong, bool).

SendEmpty(ulong)

Sends an uplink with no payload, carrying whatever the relay owes its network.

public LorawanTransmission SendEmpty(ulong nowMicros)

Parameters

nowMicros ulong

The time, in microseconds.

Returns

LorawanTransmission

What to transmit, with its receive windows.

Exceptions

LorawanRelayException

As Send(byte, ReadOnlySpan<byte>, ulong, bool).

Start(LorawanCadPeriodicity, byte, LoraRelayChannel?)

Starts scanning, or changes what a running relay scans from its next scan on.

public void Start(LorawanCadPeriodicity cadPeriodicity = LorawanCadPeriodicity.Ms1000, byte defaultChannelIndex = 0, LoraRelayChannel? secondChannel = null)

Parameters

cadPeriodicity LorawanCadPeriodicity

How often to scan.

defaultChannelIndex byte

Which of the region's wake-on-radio channels is the default.

secondChannel LoraRelayChannel?

A second channel the network configured.

Exceptions

PamojaException

The region does not define that channel.

LorawanRelayException

The configuration scans too often for its data rates.

Stop()

Stops scanning. A forwarded uplink already waiting still goes out.

public void Stop()

Trust(byte, LorawanTrustedDevice)

Trusts an end device, as an UpdateUplinkListReq with the same fields does.

public void Trust(byte index, LorawanTrustedDevice device)

Parameters

index byte

The entry, 0 to 15.

device LorawanTrustedDevice

The device, its key, and what it may spend.

Exceptions

ArgumentException

The device's key is not sixteen bytes.

PamojaException

The index is past 15.

UplinkMissed()

Clears the uplink a wake-on-radio frame announced, once listening heard nothing.

public void UplinkMissed()