Skip to content

KISS modem wrapper#36

Open
agessaman wants to merge 8 commits intorightup:feat/newRadiosfrom
agessaman:dev
Open

KISS modem wrapper#36
agessaman wants to merge 8 commits intorightup:feat/newRadiosfrom
agessaman:dev

Conversation

@agessaman
Copy link

My first draft of a wrapper. I've tested reading a variety of radio packets, handling DMs, and channel messages. I have an experimental branch of meshcore-bot that has implemented this wrapper for all radio functions.

This includes a change to modify the _on_packet_received callback in the dispatcher to optionally return RSSI and SNR on a per-packet basis to ensure they are bound to the right packet that my project would really appreciate, but if it doesn't make it I'll understand.

There's some more work to be done in ModemIdentity, which moves the crypto handling and keys to the radio. It's a little harder test test than simply pushing pyMC generated packets through the radio.

…update related documentation

- Updated radio type choices in various example scripts to include 'kiss-modem'.
- Enhanced the create_radio function to support 'kiss-modem' with specific configuration and identity handling.
- Added conditional imports for KissSerialWrapper and KissModemWrapper in the hardware module.
- Updated documentation to reflect changes in radio type options and identity creation logic.
…packet metrics

- Updated the RX callback to accept both (data) and (data, rssi, snr) signatures for improved flexibility.
- Implemented a helper function to invoke the callback with the appropriate number of arguments.
- Modified the dispatcher to handle per-packet RSSI and SNR values, ensuring accurate metrics without race conditions.
- Added a test to verify that the RX callback correctly receives per-packet RSSI and SNR values.
…allbacks

- Introduced a method to set an asyncio event loop for safe callback invocation from background threads.
- Updated the RX callback dispatcher to utilize the event loop when set, ensuring proper async integration.
- Modified the constructor and documentation to reflect changes in callback handling and configuration options.
- Added tests to verify event loop functionality and compatibility with radio configuration keys.
…ulation

- Changed method signature of calc_shared_secret to accept a 32-byte Ed25519 public key instead of X25519.
- Updated documentation to clarify the internal conversion from Ed25519 to X25519 by the modem.
- Added validation to ensure the provided public key is the correct length.
- Enhanced comments for better understanding of the key exchange process.
@agessaman
Copy link
Author

Did some testing on the ModemIdentity. Verified that it works as intended.

============================================================
Test 1: SHA-256 Hash
============================================================
Test data: b'Hello, MeshCore!'
Modem hash:  2acb6670cfe6e8803d710e04cba7a4b32d74ef92c02d3fcaed3c169d4c804944
Python hash: 2acb6670cfe6e8803d710e04cba7a4b32d74ef92c02d3fcaed3c169d4c804944
PASS: Hashes match!

============================================================
Test 2: Sign and Verify
============================================================
Message: b'Test message for signing'
Modem signature: 2951955eaa9d1c92ad058e4ebe048030a777e0084a5589272624591f14ddf1f9e8299fccc37fe1735c91f89628fbde6aa44e2c4530bb064b5fcb96daaa20cf05
Modem self-verify: True
Python verify of modem signature: True
PASS: Signature verified by both!

============================================================
Test 3: Key Exchange / Shared Secret
============================================================
Local identity pubkey: 4a911e96cd9dbd6c728934f94b1aee1b4a74bb075b7ae324596ae44e7985da3f
Modem identity pubkey: 3482f930605d43ec9bb86d04d9fa70f48386c46f945fd8670cbd18112ec45f06
Modem shared secret: 1b806e426e7f005188ac728e73b1f66eb531ff3fa0bb0c0769cd8a1605987f16
Python shared secret: 1b806e426e7f005188ac728e73b1f66eb531ff3fa0bb0c0769cd8a1605987f16
PASS: Shared secrets match!

============================================================
Test 4: Encryption/Decryption Round-trip
============================================================
Plaintext: b'Secret message for encryption test!'
Key: 1b806e426e7f005188ac728e73b1f66e...
Modem encrypted - MAC: dfc4, Ciphertext: 58ab0daa1885fdfacac23345353d63fceabf5ad65a83a1190d0cb19d186c2af36079ecf6e70d58b7cb22fc3e0c1744ed
Modem decrypted: b'Secret message for encryption test!'
PASS: Modem encrypt/decrypt round-trip works!

Cross-implementation test (Python encrypt -> Modem decrypt):
Python encrypted - MAC: dfc4, Ciphertext: 58ab0daa1885fdfacac23345353d63fceabf5ad65a83a1190d0cb19d186c2af36079ecf6e70d58b7cb22fc3e0c1744ed
Modem decrypted Python ciphertext: b'Secret message for encryption test!'
PASS: Cross-implementation encryption works!

There remains an issue with the ModemIdentity because it holds the private key, it breaks the pattern because calc_shared_secret is called on the peer's Identity, not on LocalIdentity. The LocalIdentity only provides get_private_key().

ModemIdentity.get_private_key() raises a RuntimeError there's no mechanism to get the private key from the radio, so when handlers call peer_id.calc_shared_secret(local_identity.get_private_key()), it fails if local_identity is a ModemIdentity.

There's a need for some kind of a wrapper or duck typing. I don't know what route you'd want to go with that though.

…ions

- Adjusted command constants for KISS Modem to reflect the correct values as per firmware documentation.
- Renumbered CMD and RESP constants to ensure consistency and avoid conflicts with firmware commands.
- Enhanced comments for clarity regarding the changes made to the command structure.
@rightup rightup changed the base branch from dev to feat/newRadios February 4, 2026 13:30
@agessaman agessaman marked this pull request as ready for review February 5, 2026 21:30
- Implemented LBT mechanism to check channel availability before transmission, aligning with MeshCore firmware specifications.
- Introduced LBT retry delays and maximum wait time to manage channel busy states.
- Updated send method to return detailed transmission metadata, including LBT metrics.
- Refactored timestamp retrieval in Dispatcher to use asyncio.get_running_loop for better compatibility.
- Added a cleanup method to release modem resources by disconnecting the serial and stopping threads.
- Added a check_radio_health method to verify modem connectivity and respond to pings, enhancing reliability.
- Added a get_status method to retrieve comprehensive radio status, including configuration and statistics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant