Skip to main content

Module network

Module network 

Source
Expand description

The network side of a single site: what a server does with what a gateway forwarded.

A gateway hands over packets without reading them, because it holds no keys. Deciding what a packet is, admitting the device that sent it, decrypting what it carries, and working out when and where to answer is the network server’s work, and this module does that much of it for one site: a Network holds the devices it admits, the sessions it has granted, and the counters it has seen, and turns an Rxpk into an Event.

It runs no sockets and keeps no clock. An uplink goes in as the gateway reported it, and a downlink comes back as a Txpk ready for a PULL_RESP, timed in the concentrator’s own microseconds, so the caller owns every decision about the wire.

The windows come from the published parameters rather than from habit. RP002-1.0.5 section 3.3 gives the delays that are recommended for every region, TS001-1.0.4 gives the layout of the two bytes a join accept carries, and the channel a first window answers on is regional: by default the plan decides it, and Rx1Channels can override that.

§Examples

A device joins, sends a reading, and is answered in its first receive window.

use pamoja_gateway::network::{Event, Network, Registration};
use pamoja_gateway::udp::{Eui, Rxpk};
use pamoja_lora::region::Region;
use pamoja_lora::LinkSettings;
use pamoja_lorawan::{Device, Uplink};

// What a soil probe was provisioned with: its own EUI from its label, the EUI of the
// application it joins, and its root key.
let dev_eui = Eui::from_hex("70b3d57ed0001234").expect("the probe's EUI").bytes();
let join_eui = Eui::from_hex("70b3d57ed0000000").expect("the application's EUI").bytes();
let app_key = [7; 16];

// A private network that admits it.
let mut network = Network::new(Region::Eu868.plan(), 0x00_00_2A);
network.register(Registration::new(dev_eui, join_eui, app_key));

// The gateway forwards the probe's join request, and the network grants it a session.
let probe = Device::new(dev_eui, join_eui, app_key);
let link = LinkSettings::new(7, 125_000);
let request = probe.join_request(1);
let heard = Rxpk::new(868_100_000, link, request.as_bytes().to_vec()).with_timestamp_us(1_000);
let Ok(Event::Joined { dev_addr, accept, .. }) = network.uplink(&heard) else {
    panic!("the join request verifies");
};

// The probe reads the accept and holds the session the network granted.
let session = probe
    .accept_join(&accept.payload, 1)
    .expect("the accept verifies")
    .session();
assert_eq!(session.dev_addr(), dev_addr);

// Its first reading arrives decrypted, and the answer goes out in the first receive
// window, a second after the uplink ended.
let frame = session
    .encode_uplink(&Uplink::new(0, 2, b"21.5"))
    .expect("an uplink");
let heard = Rxpk::new(868_100_000, link, frame.as_bytes().to_vec()).with_timestamp_us(9_000_000);
let Ok(Event::Data { payload, slot, .. }) = network.uplink(&heard) else {
    panic!("the reading verifies");
};
assert_eq!(payload, b"21.5");
let reply = network
    .answer(dev_addr, slot, 2, b"ok")
    .expect("the probe holds a session");
assert_eq!(reply.timestamp_us, Some(10_000_000));

Structs§

Network
The network side of one site.
Notice
A device a relay heard and could not verify, TS011-1.0.1 section 10.7.
Registration
A device the network admits, the key it was provisioned with, and the revision of the link layer it follows.
Relayed
What a relay added to an uplink it forwarded, TS011-1.0.1 section 9.1.
Slot
Where and when a downlink answers an uplink, in the concentrator’s own terms.
Windows
When and where a network answers, and at what rate.

Enums§

Event
What a forwarded packet turned out to be.
NetworkError
What can go wrong admitting or reading a forwarded packet.
Rx1Channels
The channel the first receive window answers on, which the region decides.

Constants§

JOIN_ACCEPT_DELAY1_US
The delay from the end of a join request to the first window a join accept may arrive in.
JOIN_ACCEPT_DELAY2_US
The delay to the second join accept window.
MAX_FCNT_GAP
How far ahead of the last counter it accepted a receiver follows a sender.
RECEIVE_DELAY1_US
The delay from the end of an uplink to the opening of the first receive window.
RECEIVE_DELAY2_US
The delay to the second receive window, which RP002-1.0.5 fixes at one second after the first.