Sideband 2.0.0 released
Started by Mark bc7291552be7a58f... ·
Hello good people of the ret. I have just released version 2.0.0 of Sideband. There's a lot of good stuff here. My initial plan was to yabber on for a few posts about all the new and updated stuff and post some screenshots, but I am le tired, and I honestly just want a cup of tea and to stare into the distance for a bit, so that'll have to wait till tomorrow or an approximation thereof.
Instead, I can at least leave you with the release notes for now :) Enjoy!
Voice & Calls
- Added true half-duplex mode to LXST telephony voice calls
- Added ability to switch between half and full-duplex during live calls
- Added PTT controls to the voice screen for live calls
- Added call statistics display to the call screen during calls
- Added ability to mute microphone and/or speaker during calls
Map & Telemetry
- Completely refactored the map view
- Significantly optimized the map rendering engine
- Reworked tile loading to be much faster
- With marker clustering support, the map can now render thousands of objects concurrently
- Added ability to jump/zoom directly to cluster extents by clicking on a cluster
- Added 10 new map types
- Added ability to use a custom map tile server
- Added ability to provide custom API keys for Stadia and MapTiler sources
- Added smart tile pre-fetching to reduce load times when zooming and panning
- Added option to display discovered interfaces on the map
- Added quick-toggle button for showing/hiding discovered interfaces to the map
- Added ability to view discovered interface details
- Added ability to directly use discovered interfaces and copy interface config
- Added ability to directly configure an RNode to use an interface from the map
- Added new telemetry sensor type for connectable interfaces
- Added ability to list and view connectable interface telemetry in object details
- Added ability to display connection map telemetry on the map
- Added display of signal strength and connection types for connection maps
- Added ability to display blocked entries on connection maps
- Added individual map layer toggles
- Added individual map caching directories
- Added ability to clear map caches selectively for individual maps
- Added ability to toggle between relaxed and aggresive tile loading
- Added approximate radio horizon calculation if target entry's altitude is zero
- Optimized the RNS transport node telemetry sensor for better bandwidth efficiency
- Improved the object details item rendering to be more informative and concise
- Improved marker icon rendering
- Fixed jittery map markers on zoom due to rounding errors
- Fixed a bug in map bounding box collision calculations
- Fixed local MBTiles maps not loading correctly in some cases
- Fixed invalid starting position and pan locks for some local MBTiles maps
- Added telemetry plugin example for creating interface telemetry providers
- Added telemetry plugin example for creating connection maps
Text Console
- Sideband now has an interactive text console for command-line operation
- Includes commands for commonly used operations, with tab-completion and options listing
- Includes built-in help and commands reference
- Includes the ability to use the
rawcommand to exeute of Python code within sideband - Allows streaming log output and changing log levels on the fly
- Allows direct editing of configuration and state of the running instance
- Very useful for use in headless/daemon mode, or for telemetry-only nodes
General
- Unless disabled in your RNS config, Sideband now uses ephemeral transport IDs by default
- The transport ID rotates on every app start, this behavior is default on Android as well
- Significantly improved performance of various packet processing and network tasks
- Updates the included RNS to
1.4.0and LXMF to1.1.0with performance and security fixes - Added ability to enable hop-count obfuscation from Connectivity settings
- Added incoming messages status display
- Added ability to cancel incoming messages
- Added keyboard shortcuts for going directly to the object details screen
- Improved propagation node sync feedback with size and progress information
- Reworked logging to increase clarity and reduce logging noise
- Updated all included files and documentation in the repository server to the latest versions
- Added several new keyboard shortcuts for better keyboard navigation
- Updated the keyboard shortcuts listing in the Guide section
w½e0OOOOOOIOKL...... <-- Momo says hi
Wow, very nice. Congratulations!
Wow, what a changelog! Thank you, Mark!
| The only question is: Who is Momo ? :D
Momo is reticucat :) A feral kitten I found some weeks ago, the rest of the litter was dead and the mother gone. She was completely starved and dehydrated, basically tried crawling up my leg when I found her, so what could I do? But she's strong, healthy and purring now :)
Here's a screenshot of a section of the map with around 1100 points loaded in total. Before the refactor, this would have been impossible, and completely dropped the framerate. Now it works, and with proper dynamic clustering/grouping :) Clicking/tapping on a cluster will zoom the map to the cluster's extents.
There's also scattering of close and directly overlapping points: If two points are very close to each other, they will get pushed slightly apart at the highest zoom levels. If a number of points share the exact same coordinates, they will get distributed in an expanding concentric ring pattern.
The map is now actually useful for showing many different points of interest, discovered interfaces, peers and telemetry entries :)

Thanks for this Mark, amazing work ❤️
Not sure if anybody else is having the same issue as me on Mac when running sideband?
[2026-07-22 13:45:15] [Error] Error while locating UI scale file: Can't mix strings and bytes in path components
G6PHF, in sbapp/plyer/platforms/macosx/storagepath.py, in the _get_home_dir function, can you try replacing:
return home_dir_NSURL.absoluteString.UTF8String()
With:
return home_dir_NSURL.absoluteString.UTF8String().decode("utf-8")
And let me know if that works? It's a little hard for me to debug, since I don't have access to a Mac, but it looks like it's just a string encoding issue.
Mark wrote:
G6PHF, in
sbapp/plyer/platforms/macosx/storagepath.py, in the_get_home_dirfunction, can you try replacing:return home_dir_NSURL.absoluteString.UTF8String()With:
return home_dir_NSURL.absoluteString.UTF8String().decode("utf-8")And let me know if that works? It's a little hard for me to debug, since I don't have access to a Mac, but it looks like it's just a string encoding issue.
That fixed it Mark, many thanks!
Nice, good to hear. I'll include that fix in the next release. Could you do me a favor and test if changing the UI scale in preferences actually works? Ie., if setting the UI scale, then closing Sideband and re-opening it actually does change the overall UI scaling?
Yes I can confirm that changing the scaling and restarting, changes the scaling to the new value.
All good that I can see. Thanks
Very good, I'll include it then, thanks for checking!
Mark wrote:
Very good, I'll include it then, thanks for checking!
No problem, happy to help.
One thing I noticed is that I am not seeing hardly any nodes or interfaces on my map as you are?
I assume I am missing a setting to display some of these?

It may just be because your instance hasn't had time to discover enough interfaces yet. Generally, other nodes announce interfaces only one or two times every 24 hours, so if you leave the program running overnight (or at least just rnsd running), you should see the map populate.
This of course requires that you have discover_interfaces = yes in the config (in Sideband on Android this is turned on by default, though). You can also lower required_discovery_value, for the map above, I had it set pretty low, something like 10 or 12, I think, to just collect a lot of interfaces to test the map, and it was running on a system that had already collected a lot of interfaces.
Hi Mark,
I've hit what I think is a small platform issue on macOS that you'd may want to know about.
Symptom: The new interface discovery system finds public hubs and auto-connects to them as BackboneInterfaces, but every attempt fails on macOS with:
[Warning] Initial connection for BackboneInterface[rns.st/rns.st:4242] could not be established: module 'select' has no attribute 'epoll' [Warning] Leaving unconnected and retrying connection in 5 seconds.
This repeats every few seconds for each discovered hub, indefinitely. Occasionally followed by:
[Error] Error while shutting down socket for BackboneInterface[...]: [Errno 57] Socket is not connected
select.epoll is Linux-only, and macOS only provides kqueue, so the epoll-based I/O in BackboneInterface can't run on Darwin. It seems the auto-connect logic doesn't check platform support before selecting BackboneInterface as the connection type for discovered peers.
Cheers.
A bit of further digging in the installed package suggests where it lives: LocalInterface.py guards all its epoll usage behind platformutils.use_epoll() with a non-epoll fallback path, but BackboneInterface.py's ensure_epoll() calls select.epoll() unconditionally with no platform check or kqueue backend.
So when discovery auto-connect spawns a BackboneInterface on Darwin, it fails immediately. Presumably either the auto-connect should consult use_epoll() and fall back to TCPClientInterface, or BackboneInterface needs the same dual-backend treatment as LocalInterface.
Yeah, that's actually right. It should use the old TCPClientInterface on Mac for now. In RNS/Discovery.py, you should be able to change line 334 (or thereabouts) from:
backbone_support = not RNS.vendor.platformutils.is_windows()
To:
backbone_support = not RNS.vendor.platformutils.is_windows() and not RNS.vendor.platformutils.is_darwin()
And it should work. I'll have that included in the next release.
There is actually a full kqueue implementation for backbone interface support in the dev_bsd branch on Aleph, but I haven't had time to properly test it yet, and I don't have a Mac to test things on for the Mac side of things, which further complicates the whole thing a bit (also why I had to drop the mac dmg builds a while back). That branch has all the required logic everywhere to switch between epoll and kqueue.