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#.
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
pamoja.lorawanreference, every class and function in this module.- The LoRaWAN guide, with the same example in Rust, TypeScript, and C#.
- Every capability, and the install page.
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)
| File | Size | Uploaded | |
|---|---|---|---|
| pamoja_lorawan-0.2.0.tar.gz | 14.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|