Expand description
LoRaWAN gateway protocols for the pamoja SDK.
A LoRa gateway is a radio with an uplink: it hears packets from every node in range and hands them to a network server, which hands back the packets to transmit. The protocol between the two is not LoRaWAN, which is what the packets themselves carry; it is a separate, deliberately plain exchange of UDP datagrams, and this crate speaks it from both sides.
udp- the Semtech packet forwarder protocol: the PUSH_DATA and PULL_DATA datagrams a gateway sends, the PUSH_ACK, PULL_ACK and PULL_RESP a server answers with, the TX_ACK that reports what became of a downlink, and therxpk,stat,txpkandtxpk_ackobjects they carry.base64- the payload encoding of RFC 4648, padded on the way out and read either way on the way in, because gateways in the field send both.time- the two timestamp formats the protocol prescribes, to the microsecond for a reception and to the second for a gateway’s own clock.network, with thenetworkfeature - the network side of one site: admitting a join, reading an uplink, and working out where and when to answer it.bridge, with thebridgefeature - carrying messages between the radio the nodes are on and the link that leaves the site, under a prefix that names the site.daemon, with thedaemonfeature - what a gateway program is told to do, and the order a concentrator is brought up and forwarded from.station- the LoRa Basics Station protocol: the discovery request that finds a network server, and the messages the websocket carries once one is open.chirpstack- the uplink events a ChirpStack network server publishes on MQTT, read into the device, the payload and the gateways that heard it.
Every datagram is data: the crate builds and parses them, and leaves the socket, the keepalive, and the scheduling to the program that owns them.
§Examples
A gateway forwards a packet it heard, and the server reads it and acknowledges it.
use pamoja_gateway::udp::{Eui, Packet, PacketKind, Rxpk, Uplink};
use pamoja_lora::LinkSettings;
// A gateway names itself by its Ethernet address with FF FE in the middle, written
// the way a network server's console shows it.
let gateway = Eui::from_hex("b827ebfffe010203").expect("sixteen hex digits");
// What its radio heard: a reading at SF7 on 868.1 MHz, and how strongly it arrived.
let heard = Rxpk::new(868_100_000, LinkSettings::new(7, 125_000), b"21.5".to_vec())
.with_rssi_dbm(-35)
.with_snr_db(5.1);
// It forwards the packet with a token of its choosing, which the answer carries back.
let forwarded = Packet::PushData {
token: 1,
gateway,
uplink: Uplink::from(heard),
};
let datagram = forwarded.to_bytes();
// The server reads back exactly what was sent: who sent it, and what was heard.
let received = Packet::parse(&datagram).expect("a well-formed datagram");
assert_eq!(received, forwarded);
assert_eq!(received.gateway(), Some(gateway));
if let Packet::PushData { uplink, .. } = &received {
assert_eq!(uplink.packets[0].frequency_hz, 868_100_000);
assert_eq!(uplink.packets[0].payload, b"21.5");
}
// And answers with the acknowledgment the protocol owes it, under the same token.
let ack = received.acknowledgment().expect("a PUSH_DATA is acknowledged");
assert_eq!(ack.kind(), PacketKind::PushAck);
assert_eq!(ack.token(), forwarded.token());Modules§
- base64
- The base64 encoding of RFC 4648, which the protocol carries every radio payload in.
- chirpstack
- Reading what a ChirpStack network server publishes about the devices it hears.
- network
- The network side of a single site: what a server does with what a gateway forwarded.
- station
- The LoRa Basics Station protocol, both sides.
- time
- The two timestamp formats the packet forwarder protocol prescribes.
- udp
- The Semtech packet forwarder protocol, both sides.