Skip to main content

pamoja-lorawan

LoRaWAN 1.0.x MAC framing, AES-CMAC and AES encryption, and both halves of the OTAA join. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.

read the guide documentation API reference

Install

pip install pamoja-lorawan
from pamoja import lorawan

This pulls in pamoja-native, the compiled engine. pip install pamoja is the whole framework in one package.

Example

The script the test suite runs, spliced here as it ran.

From bindings/python/guides/lorawan.py:

from pamoja.core import PamojaError
from pamoja.lorawan import device, grant

# The root key is provisioned into the device at the factory and known to the network
# server. It is the only secret either side starts with; any 16 bytes stand in here.
app_key = bytes([7]) * 16

# The device asks to join with a nonce it has not used before, which is what stops an old
# accept being replayed at it.
dev_nonce = 1
node = device(bytes(8), bytes(8), app_key)

# The network grants the join. It draws its own nonce, names the network the device is
# joining, and assigns the address the device will answer to from then on.
dev_addr = 0x26012E43
offer = grant(app_nonce=2, net_id=19, dev_addr=dev_addr)
accept = offer.accept(app_key, dev_nonce)
print(f"granted   address 0x{dev_addr:08X} in a {len(accept)}-byte accept")

# The device verifies it against the root key. A join accept carries no device identifier,
# so only that key decides whether it is for this device.
joined = node.accept_join(accept, dev_nonce)
print(f"joined    the device took address 0x{joined.dev_addr:08X}")

# Neither side transmits a session key. Both derive the same pair from the root key and the
# two nonces, so the network reads what the device sends without ever having been told how.
network = offer.session(app_key, dev_nonce)
uplink = joined.session().encode_uplink(1, 1, b"level=high")
received = network.decode(uplink, 1)
print(f"uplink    the network read {received.payload.decode()}")

# A single byte changed in the air fails that check, so no one else can admit the device or
# put words in its mouth.
forged = bytearray(accept)
forged[1] ^= 0xFF
try:
    node.accept_join(bytes(forged), dev_nonce)
    print("a forged accept was taken, which should never happen")
except PamojaError as error:
    print(f"forged    accept refused: {error}")

The same capability in every language

Language Package Reference
Rust pamoja-lorawan reference, docs.rs, install
TypeScript @pamoja/lorawan reference, install
Python pamoja-lorawan reference, install
C# Pamoja.Lorawan reference, install

Documentation

License

MIT

Release files for pamoja-lorawan 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pamoja-lorawan 0.2.0
File Size Uploaded
pamoja_lorawan-0.2.0.tar.gz 14.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pamoja-lorawan 0.2.0
File Interpreter ABI Platform
pamoja_lorawan-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.0 kB

Release files / pamoja_lorawan-0.2.0.tar.gz

Download URL pamoja_lorawan-0.2.0.tar.gz
Size 14.6 kB
Tags Source
SHA-256 checksum
How to use checksums
13512ef71672b941635a7cda850c59bbacfb8a6f3bd5dd7ee4e8545eb2be2472
BLAKE2b-256 checksum
How to use checksums
4345abad3e870b87a4e46470c0b8374576b2f06534071b6f4aab867651ff27a2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / pamoja_lorawan-0.2.0-py3-none-any.whl

Download URL pamoja_lorawan-0.2.0-py3-none-any.whl
Size 17.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3c8b4e3b5a9f6fded4384c8eee62aa0c1354d6a901dfc2e8618c1814f924bbe4
BLAKE2b-256 checksum
How to use checksums
eb0e162626f2cdb8f5197258d3aac8c1ddbeaa4b12fc37f2a6331a581520b225
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.18

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page