### Announce Example Setup Source: https://reticulum.network/manual/examples.html Sets up the Reticulum network and argument parsing for the announce example. Handles configuration path and catches keyboard interrupts. ```python if __name__ == "__main__": try: parser = argparse.ArgumentParser( description="Reticulum example that demonstrates announces and announce handlers" ) parser.add_argument( "--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str ) args = parser.parse_args() if args.config: configarg = args.config else: configarg = None program_setup(configarg) except KeyboardInterrupt: print("") sys.exit(0) ``` -------------------------------- ### Reticulum Announce Setup Source: https://reticulum.network/manual/examples.html Builds upon the minimal example to demonstrate setting up announce callbacks for receiving notifications about relevant destination announces. Requires the 'RNS' library. ```python ########################################################## # This RNS example demonstrates setting up announce # # callbacks, which will let an application receive a # # notification when an announce relevant for it arrives # ########################################################## import argparse import random import sys import RNS # Let's define an app name. We'll use this for all # destinations we create. Since this basic example # is part of a range of example utilities, we'll put # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" ``` -------------------------------- ### Filetransfer Server/Client Example Setup in Reticulum Source: https://reticulum.network/manual/examples.html Initializes constants and variables for a Reticulum file transfer example, including application name and default timeout. ```python # Let's define an app name. We'll use this for all # destinations we create. Since this echo example # is part of a range of example utilities, we'll put # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" # We'll also define a default timeout, in seconds APP_TIMEOUT = 45.0 ########################################################## #### Server Part ######################################### ########################################################## serve_path = None # This initialisation is executed when the users chooses ``` -------------------------------- ### Generate example Reticulum configuration Source: https://reticulum.network/manual/gettingstartedfast.html Generate an example Reticulum configuration file. This file can be used as a starting point for customizing network interfaces. ```bash rnsd --exampleconfig ``` -------------------------------- ### Echo Example Introduction Source: https://reticulum.network/manual/examples.html Introduces the Echo example, which demonstrates communication between two destinations using the Packet interface for a client/server echo utility. ```python ########################################################## # This RNS example demonstrates a simple client/server # # echo utility. A client can send an echo request to the # # server, and the server will respond by proving receipt # ``` -------------------------------- ### Start and Enable Systemd Service Source: https://reticulum.network/manual/using.html Manually start the rnsd service or enable it to start automatically at boot using systemctl commands. ```bash sudo systemctl start rnsd ``` ```bash sudo systemctl enable rnsd ``` -------------------------------- ### Complete Page Node Configuration Example Source: https://reticulum.network/manual/git.html A comprehensive configuration example for the page node, including node name, repository paths, access controls, and page serving options. ```ini [rngit] node_name = My Git Node announce_interval = 360 record_stats = yes [repositories] public = /var/git/public internal = /var/git/internal [access] public = r:all internal = rw:9710b86ba12c42d1d8f30f74fe509286 [pages] serve_nomadnet = yes unicode_icons = no ``` -------------------------------- ### Minimal Reticulum Network Setup Source: https://reticulum.network/manual/examples.html Demonstrates the bare-minimum setup to connect to a Reticulum network, initialize the stack, create a destination, and send an announce. Requires the 'RNS' library. ```python ########################################################## # This RNS example demonstrates a minimal setup, that # # will start up the Reticulum Network Stack, generate a # # new destination, and let the user send an announce. # ########################################################## import argparse import sys import RNS # Let's define an app name. We'll use this for all # destinations we create. Since this basic example # is part of a range of example utilities, we'll put # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" # This initialisation is executed when the program is started def program_setup(configpath): # We must first initialise Reticulum reticulum = RNS.Reticulum(configpath) # Randomly create a new identity for our example identity = RNS.Identity() # Using the identity we just created, we create a destination. # Destinations are endpoints in Reticulum, that can be addressed # and communicated with. Destinations can also announce their # existence, which will let the network know they are reachable # and automatically create paths to them, from anywhere else # in the network. destination = RNS.Destination( identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "minimalsample" ) # We configure the destination to automatically prove all # packets addressed to it. By doing this, RNS will automatically # generate a proof for each incoming packet and transmit it # back to the sender of that packet. This will let anyone that # tries to communicate with the destination know whether their # communication was received correctly. destination.set_proof_strategy(RNS.Destination.PROVE_ALL) # Everything's ready! # Let's hand over control to the announce loop announceLoop(destination) def announceLoop(destination): # Let the user know that everything is ready RNS.log( "Minimal example "+ RNS.prettyhexrep(destination.hash)+ " running, hit enter to manually send an announce (Ctrl-C to quit)" ) # We enter a loop that runs until the users exits. # If the user hits enter, we will announce our server # destination on the network, which will let clients # know how to create messages directed towards it. while True: entered = input() destination.announce() RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash)) ########################################################## #### Program Startup ##################################### ########################################################## # This part of the program gets run at startup, # and parses input from the user, and then starts # the desired program mode. if __name__ == "__main__": try: parser = argparse.ArgumentParser( description="Minimal example to start Reticulum and create a destination" ) parser.add_argument( "--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str ) args = parser.parse_args() if args.config: configarg = args.config else: configarg = None program_setup(configarg) except KeyboardInterrupt: print("") sys.exit(0) ``` -------------------------------- ### Install Reticulum with pip Source: https://reticulum.network/manual/hardware.html Install the Reticulum library using pip. Ensure Python 3 and pip are installed on your system. ```bash pip install rns ``` -------------------------------- ### Generate Verbose rnsd Configuration Example Source: https://reticulum.network/manual/using.html Generates a detailed configuration example for rnsd, including explanations of various options and interface configurations. This is useful for understanding and setting up Reticulum. ```bash $ rnsd --exampleconfig ``` -------------------------------- ### Install Python and development packages on RISC-V Source: https://reticulum.network/manual/gettingstartedfast.html On RISC-V and similar architectures, install Python, pip, and development packages to ensure pip can build missing dependencies locally. ```bash # Install Python and development packages sudo apt update sudo apt install python3 python3-pip python3-dev ``` -------------------------------- ### Start and Enable Userspace Systemd Service Source: https://reticulum.network/manual/using.html Reload the systemd daemon, start the user service, and optionally enable it to start automatically without requiring a login. Ensure linger is enabled for the user. ```bash systemctl --user daemon-reload systemctl --user start rnsd.service ``` ```bash sudo loginctl enable-linger USERNAMEHERE systemctl --user enable rnsd.service ``` -------------------------------- ### Install Reticulum from local wheel file Source: https://reticulum.network/manual/gettingstartedfast.html Install Reticulum using a downloaded wheel file with pip. This is useful for offline installations or specific versions. ```bash pip install ./rns-1.1.2-py3-none-any.whl ``` -------------------------------- ### Start rngit Repository Node Source: https://reticulum.network/manual/git.html Run this command to start the `rngit` node, which hosts Git repositories over Reticulum. It creates a default configuration file on the first run. ```bash $ rngit [Notice] Starting Reticulum Git Node... [Notice] Reticulum Git Node listening on <0d7334d411d00120cbad24edf355fdd2> ``` -------------------------------- ### Install Reticulum with pip Source: https://reticulum.network/manual/gettingstartedfast.html Use this command to install the Reticulum Network Stack using the pip package manager. Ensure pip is installed first. ```bash pip install rns ``` -------------------------------- ### Auto-install RNode Firmware Source: https://reticulum.network/manual/hardware.html Use the `rnodeconf` utility in auto-install mode to install and configure RNode firmware on your devices. Follow the on-screen prompts for hardware-specific questions. ```bash rnodeconf --autoinstall ``` -------------------------------- ### Install Pygments for Syntax Highlighting Source: https://reticulum.network/manual/git.html Install the pygments Python module to enable automatic syntax highlighting for code files served by the rngit page node. ```bash pip install pygments ``` -------------------------------- ### Configure Public Backbone Gateway Source: https://reticulum.network/manual/interfaces.html Example configuration for a public backbone gateway that is discoverable by anyone on the network. It includes details for announcing the interface and setting a high stamp value. ```toml [[My Public Gateway]] type = BackboneInterface mode = gateway listen_on = 0.0.0.0 port = 4242 # Enable Discovery discoverable = yes # Interface Details discovery_name = Region A Public Entrypoint announce_interval = 720 # Use external script to resolve dynamic IP reachable_on = /usr/local/bin/get_external_ip.sh # Generate high stamp value discovery_stamp_value = 24 # Optional location data latitude = 51.99714 longitude = -0.74195 height = 15 ``` -------------------------------- ### Initialize Reticulum App with Name Source: https://reticulum.network/manual/examples.html Defines the application name used for all destinations created within this RNS example utility. ```python # Let's define an app name. We'll use this for all # destinations we create. Since this echo example # is part of a range of example utilities, we'll put # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" ``` -------------------------------- ### Initialize Reticulum Application Source: https://reticulum.network/manual/examples.html Sets up the application name for Reticulum destinations and initializes the RNS library. This is a boilerplate setup for Reticulum applications. ```python # Let's define an app name. We'll use this for all # destinations we create. Since this echo example # is part of a range of example utilities, we'll put # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" ########################################################## #### Server Part ######################################### ########################################################## # A reference to the latest client link that connected latest_client_link = None # This initialisation is executed when the users chooses ``` -------------------------------- ### Implement Custom RNS Interface Source: https://reticulum.network/manual/examples.html This example shows how to create a custom interface by subclassing the RNS Interface class. It includes handling serial port dependencies and configuration parameters. ```python class ExampleInterface(Interface): DEFAULT_IFAC_SIZE = 8 owner = None port = None speed = None databits = None parity = None stopbits = None serial = None def __init__(self, owner, configuration): import importlib if importlib.util.find_spec('serial') != None: import serial else: RNS.log("Using this interface requires a serial communication module to be installed.", RNS.LOG_CRITICAL) RNS.log("You can install one with the command: python3 -m pip install pyserial", RNS.LOG_CRITICAL) RNS.panic() super().__init__() ifconf = Interface.get_config_obj(configuration) name = ifconf["name"] self.name = name port = ifconf["port"] if "port" in ifconf else None speed = int(ifconf["speed"]) if "speed" in ifconf else 9600 databits = int(ifconf["databits"]) if "databits" in ifconf else 8 parity = ifconf["parity"] if "parity" in ifconf else "N" stopbits = int(ifconf["stopbits"]) if "stopbits" in ifconf else 1 if port == None: raise ValueError(f"No port specified for {self}") self.HW_MTU = 564 self.online = False self.bitrate = speed self.pyserial = serial self.serial = None self.owner = owner self.port = port self.speed = speed self.databits = databits self.parity = serial.PARITY_NONE self.stopbits = stopbits self.timeout = 100 if parity.lower() == "e" or parity.lower() == "even": self.parity = serial.PARITY_EVEN if parity.lower() == "o" or parity.lower() == "odd": self.parity = serial.PARITY_ODD try: self.open_port() except Exception as e: RNS.log("Could not open serial port for interface "+str(self), RNS.LOG_ERROR) raise e if self.serial.is_open: self.configure_device() else: raise IOError("Could not open serial port") def open_port(self): RNS.log("Opening serial port "+self.port+"...", RNS.LOG_VERBOSE) self.serial = self.pyserial.Serial( port = self.port, baudrate = self.speed, bytesize = self.databits, parity = self.parity, stopbits = self.stopbits, xonxoff = False, rtscts = False, timeout = 0, inter_byte_timeout = None, write_timeout = None, dsrdtr = False, ) ``` -------------------------------- ### Markdown Code Block with Language Hint Source: https://reticulum.network/manual/git.html Example of a Markdown code block with a language hint for syntax highlighting. The page node will use this hint to apply appropriate highlighting if pygments is installed. ```markdown ```python def hello_world(): print("Hello, Reticulum!") ``` ``` -------------------------------- ### Install Reticulum on OpenWRT using pip Source: https://reticulum.network/manual/gettingstartedfast.html Install Reticulum on OpenWRT systems after installing the required dependencies. This command uses pip for installation. ```bash # Install Reticulum pip install rns ``` -------------------------------- ### Client: Initialize and Connect to Server Source: https://reticulum.network/manual/examples.html Initializes Reticulum, resolves the server's destination, and establishes a link. It includes error handling for invalid destination input and checks for an existing path. ```python # A reference to the server link server_link = None # A reference to the buffer object, needed to share the # object from the link connected callback to the client # loop. buffer = None # This initialisation is executed when the users chooses # to run as a client def client(destination_hexhash, configpath): # We need a binary representation of the destination # hash that was entered on the command line try: dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2 if len(destination_hexhash) != dest_len: raise ValueError( "Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2) ) destination_hash = bytes.fromhex(destination_hexhash) except: RNS.log("Invalid destination entered. Check your input!\n") sys.exit(0) # We must first initialise Reticulum reticulum = RNS.Reticulum(configpath) # Check if we know a path to the destination if not RNS.Transport.has_path(destination_hash): RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...") RNS.Transport.request_path(destination_hash) while not RNS.Transport.has_path(destination_hash): time.sleep(0.1) # Recall the server identity server_identity = RNS.Identity.recall(destination_hash) # Inform the user that we'll begin connecting RNS.log("Establishing link with server...") # When the server identity is known, we set # up a destination server_destination = RNS.Destination( server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "bufferexample" ) # And create a link link = RNS.Link(server_destination) # We'll also set up functions to inform the # user when the link is established or closed link.set_link_established_callback(link_established) link.set_link_closed_callback(link_closed) # Everything is set up, so let's enter a loop # for the user to interact with the example client_loop() ``` -------------------------------- ### Install pipx and Reticulum on Ubuntu Source: https://reticulum.network/manual/gettingstartedfast.html Use `pipx` to install Reticulum on newer Ubuntu versions where direct `pip` system installations are restricted. Ensure installed programs are available on the command line. ```bash # Install pipx sudo apt install pipx # Make installed programs available on the command line pipx ensurepath # Install Reticulum pipx install rns ``` -------------------------------- ### Handle Client Connection Establishment Source: https://reticulum.network/manual/examples.html Callback function executed when a client successfully establishes a link to the server destination. It sets up packet and closure callbacks for the new link. ```python # When a client establishes a link to our server # destination, this function will be called with # a reference to the link. def client_connected(link): global latest_client_link RNS.log("Client connected") link.set_link_closed_callback(client_disconnected) link.set_packet_callback(server_packet_received) latest_client_link = link ``` -------------------------------- ### Install Reticulum with system package override Source: https://reticulum.network/manual/gettingstartedfast.html Use this flag when installing Reticulum with pip if your platform limits user package installations. This flag does not break system packages unless Reticulum was installed via the OS package manager. ```bash pip install rns --break-system-packages ``` -------------------------------- ### Configure Backbone Interface Listener Source: https://reticulum.network/manual/interfaces.html Use these examples to set up a Backbone interface to listen for incoming connections on specified IP addresses, ports, or network devices. Supports binding to all interfaces, specific IPs, or network devices. ```ini # This example demonstrates a backbone interface # that listens for incoming connections on the # specified IP address and port number. [[Backbone Listener]] type = BackboneInterface enabled = yes listen_on = 0.0.0.0 port = 4242 # Alternatively you can bind to a specific IP [[Backbone Listener]] type = BackboneInterface enabled = yes listen_on = 10.0.0.88 port = 4242 # Or a specific network device [[Backbone Listener]] type = BackboneInterface enabled = yes device = eth0 port = 4242 ``` ```ini # This example demonstrates a backbone interface # listening on the IPv6 address of a specified # kernel networking device. [[Backbone Listener]] type = BackboneInterface enabled = yes prefer_ipv6 = yes device = eth0 port = 4242 ``` ```ini # This example demonstrates a backbone interface # listening for connections over Yggdrasil. [[Yggdrasil Backbone Interface]] type = BackboneInterface enabled = yes device = tun0 port = 4343 ``` -------------------------------- ### Configure Public Gateway Interface Source: https://reticulum.network/manual/gettingstartedfast.html This example demonstrates a BackboneInterface configured for acting as a gateway for users to connect to either a public or private network. It is essential to configure sensible announce rate targets on publicly available interfaces. ```ini # This example demonstrates a backbone interface # configured for acting as a gateway for users to # connect to either a public or private network [[Public Gateway]] type = BackboneInterface enabled = yes mode = gateway listen_on = 0.0.0.0 port = 4242 # On publicly available interfaces, it is # essential to configure sensible announce # rate targets. announce_rate_target = 3600 announce_rate_penalty = 3600 announce_rate_grace = 6 ``` -------------------------------- ### Install Reticulum dependencies on OpenWRT Source: https://reticulum.network/manual/gettingstartedfast.html Install necessary dependencies for Reticulum on OpenWRT systems using the opkg package manager before installing Reticulum itself. ```bash # Install dependencies opkg install python3 python3-pip python3-cryptography python3-pyserial ``` -------------------------------- ### Configure TCP Server Interface Source: https://reticulum.network/manual/interfaces.html Use this to set up a basic TCP server interface. It listens on a specified port and device. ```ini [[TCP Server Interface]] type = TCPServerInterface enabled = yes prefer_ipv6 = True device = eth0 port = 4242 ``` -------------------------------- ### Install Reticulum on ARM64 Source: https://reticulum.network/manual/gettingstartedfast.html Install Python and development packages on ARM64 systems before installing Reticulum. This ensures pip can build any missing dependencies locally. ```bash # Install Python and development packages sudo apt update sudo apt install python3 python3-pip python3-dev # Install Reticulum python3 -m pip install rns ``` -------------------------------- ### Initialize Reticulum Client and Connect Source: https://reticulum.network/manual/examples.html Initializes the Reticulum library, discovers a path to the destination, and establishes a link with the server. Ensure the destination hash is valid and the configuration path is correct. ```python def client(destination_hexhash, configpath): # We need a binary representation of the destination # hash that was entered on the command line try: dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2 if len(destination_hexhash) != dest_len: raise ValueError( "Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2) ) destination_hash = bytes.fromhex(destination_hexhash) except: RNS.log("Invalid destination entered. Check your input!\n") sys.exit(0) # We must first initialise Reticulum reticulum = RNS.Reticulum(configpath) # Check if we know a path to the destination if not RNS.Transport.has_path(destination_hash): RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...") RNS.Transport.request_path(destination_hash) while not RNS.Transport.has_path(destination_hash): time.sleep(0.1) # Recall the server identity server_identity = RNS.Identity.recall(destination_hash) # Inform the user that we'll begin connecting RNS.log("Establishing link with server...") # When the server identity is known, we set # up a destination server_destination = RNS.Destination( server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "requestexample" ) # And create a link link = RNS.Link(server_destination) # We'll set up functions to inform the # user when the link is established or closed link.set_link_established_callback(link_established) link.set_link_closed_callback(link_closed) # Everything is set up, so let's enter a loop # for the user to interact with the example client_loop() ``` -------------------------------- ### Install Reticulum on Raspberry Pi using pip Source: https://reticulum.network/manual/gettingstartedfast.html Install Reticulum on Raspberry Pi OS using pip after installing dependencies. The `--break-system-packages` flag might be needed. ```bash # Install Reticulum pip install rns --break-system-packages ``` -------------------------------- ### Install Reticulum on RISC-V using pip Source: https://reticulum.network/manual/gettingstartedfast.html Install Reticulum on RISC-V systems using pip after ensuring development packages are installed. This allows pip to build any necessary local dependencies. ```bash # Install Reticulum python3 -m pip install rns ``` -------------------------------- ### Install Reticulum with Pipx on Debian Bookworm Source: https://reticulum.network/manual/gettingstartedfast.html On Debian Bookworm and later, use pipx to install Reticulum in an isolated environment. This command ensures installed programs are available on the command line. ```bash # Install pipx sudo apt install pipx # Install installed programs available on the command line pipx ensurepath # Install Reticulum pipx install rns ``` -------------------------------- ### List All Releases for a Repository Source: https://reticulum.network/manual/git.html View all published releases for a given repository. This command displays a table with tag, status, creation date, object count, and notes for each release. ```bash $ rngit release rns://50824b711717f97c2fb1166ceddd5ea9/public/myrepo list ``` -------------------------------- ### Reticulum Packet Example 2 (Type 1 Header) Source: https://reticulum.network/manual/understanding.html Demonstrates a packet with a Type 1 header, indicating a single 16-byte address field. This example also shows the header byte breakdown, highlighting differences in Propagation Type and Header Type compared to the Type 2 example. ```text +- Packet Example -+ HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD _______|_______ _______|_______ ________|______ __|_ | | | | | | | | 00000000 00000111 [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA] || | | | | || | | | +-- Hops = 7 || | | +------- Packet Type = DATA || | +--------- Destination Type = SINGLE || +----------- Propagation Type = BROADCAST |+------------- Header Type = HEADER_1 (two byte header, one address field) +-------------- Access Codes = DISABLED ``` -------------------------------- ### Install Reticulum on Android with Termux Source: https://reticulum.network/manual/gettingstartedfast.html Install Python, cryptography, and Reticulum within the Termux environment on Android. Ensure packages and indexes are up to date before proceeding. ```bash # First, make sure indexes and packages are up to date. pkg update pkg upgrade # Then install python and the cryptography library. pkg install python python-cryptography # Make sure pip is up to date, and install the wheel module. pip install wheel pip --upgrade # Install Reticulum pip install rns ``` -------------------------------- ### Server: Handle Client Connection and Callbacks Source: https://reticulum.network/manual/examples.html Sets up callbacks for client connection, disconnection, and packet reception on the server side. Ensures the server logs client events and processes incoming data. ```python def client_connected(link): global latest_client_link RNS.log("Client connected") link.set_link_closed_callback(client_disconnected) link.set_packet_callback(server_packet_received) link.set_remote_identified_callback(remote_identified) latest_client_link = link def client_disconnected(link): RNS.log("Client disconnected") def remote_identified(link, identity): RNS.log("Remote identified as: "+str(identity)) def server_packet_received(message, packet): global latest_client_link # Get the originating identity for display remote_peer = "unidentified peer" if packet.link.get_remote_identity() != None: remote_peer = str(packet.link.get_remote_identity()) # When data is received over any active link, # it will all be directed to the last client # that connected. text = message.decode("utf-8") RNS.log("Received data from "+remote_peer+": "+text) reply_text = "I received \""+text+"\" over the link from "+remote_peer reply_data = reply_text.encode("utf-8") RNS.Packet(latest_client_link, reply_data).send() ``` -------------------------------- ### Install Development Essentials for pip Source: https://reticulum.network/manual/gettingstartedfast.html Install development tools required for pip to compile missing dependencies from source. This is useful when binary packages are unavailable. ```bash # Debian / Ubuntu / Derivatives sudo apt install build-essential # Arch / Manjaro / Derivatives sudo pamac install base-devel # Fedora sudo dnf groupinstall "Development Tools" "Development Libraries" ``` -------------------------------- ### External Script for Reachable On Source: https://reticulum.network/manual/interfaces.html This script example demonstrates how to dynamically resolve an external IP address using `curl`. Ensure the script has execute permissions and handles potential network failures gracefully. ```bash #!/bin/bash curl -s ip.me exit $? ``` -------------------------------- ### Update Menu State on Download Start Source: https://reticulum.network/manual/examples.html This function is called when Reticulum detects that a download has started. It updates the menu mode and tracks download progress. ```python # When RNS detects that the download has # started, we'll update our menu state # so the user can be shown a progress of # the download. def download_began(resource): global menu_mode, current_download, download_started, transfer_size, file_size current_download = resource if download_started == 0: download_started = time.time() transfer_size += resource.size file_size = resource.total_size menu_mode = "downloading" ``` -------------------------------- ### Announce Loop and Sending Announces Source: https://reticulum.network/manual/examples.html Manages the main loop for the announce example, allowing the user to trigger manual announces by pressing Enter. It randomly selects data (fruits or noble gases) to send with each announce. ```python def announceLoop(destination_1, destination_2): # Let the user know that everything is ready RNS.log("Announce example running, hit enter to manually send an announce (Ctrl-C to quit)") # We enter a loop that runs until the users exits. # If the user hits enter, we will announce our server # destination on the network, which will let clients # know how to create messages directed towards it. while True: entered = input() # Randomly select a fruit fruit = fruits[random.randint(0,len(fruits)-1)] # Send the announce including the app data destination_1.announce(app_data=fruit.encode("utf-8")) RNS.log( "Sent announce from "+ RNS.prettyhexrep(destination_1.hash)+ " ("+destination_1.name+")" ) # Randomly select a noble gas noble_gas = noble_gases[random.randint(0,len(noble_gases)-1)] # Send the announce including the app data destination_2.announce(app_data=noble_gas.encode("utf-8")) RNS.log( "Sent announce from "+ RNS.prettyhexrep(destination_2.hash)+ " ("+destination_2.name+")" ) ``` -------------------------------- ### Start rnsd with debug logging on OpenWRT Source: https://reticulum.network/manual/gettingstartedfast.html Start the Reticulum daemon (rnsd) with verbose debug logging enabled. This is useful for troubleshooting on OpenWRT systems. ```bash # Start rnsd with debug logging enabled rnsd -vvv ``` -------------------------------- ### RNode Configuration Utility Usage Source: https://reticulum.network/manual/using.html This displays all available command-line options for the rnodeconf utility. Use these flags to interact with RNode devices for configuration and management. ```bash usage: rnodeconf [-h] [-i] [-a] [-u] [-U] [--fw-version version] [--fw-url url] [--nocheck] [-e] [-E] [-C] [--baud-flash baud_flash] [-N] [-T] [-b] [-B] [-p] [-D i] [--display-addr byte] [--freq Hz] [--bw Hz] [--txp dBm] [--sf factor] [--cr rate] [--eeprom-backup] [--eeprom-dump] [--eeprom-wipe] [-P] [--trust-key hexbytes] [--version] [-f] [-r] [-k] [-S] [-H FIRMWARE_HASH] [--platform platform] [--product product] [--model model] [--hwrev revision] port RNode Configuration and firmware utility. This program allows you to change various settings and startup modes of RNode. It can also install, flash and update the firmware on supported devices. positional arguments: port serial port where RNode is attached options: -h, --help show this help message and exit -i, --info Show device info -a, --autoinstall Automatic installation on various supported devices -u, --update Update firmware to the latest version -U, --force-update Update to specified firmware even if version matches or is older than installed version --fw-version version Use a specific firmware version for update or autoinstall --fw-url url Use an alternate firmware download URL --nocheck Don't check for firmware updates online -e, --extract Extract firmware from connected RNode for later use -E, --use-extracted Use the extracted firmware for autoinstallation or update -C, --clear-cache Clear locally cached firmware files --baud-flash baud_flash Set specific baud rate when flashing device. Default is 921600 -N, --normal Switch device to normal mode -T, --tnc Switch device to TNC mode -b, --bluetooth-on Turn device bluetooth on -B, --bluetooth-off Turn device bluetooth off -p, --bluetooth-pair Put device into bluetooth pairing mode -D, --display i Set display intensity (0-255) -t, --timeout s Set display timeout in seconds, 0 to disable -R, --rotation rotation Set display rotation, valid values are 0 through 3 --display-addr byte Set display address as hex byte (00 - FF) --recondition-display Start display reconditioning --np i Set NeoPixel intensity (0-255) --freq Hz Frequency in Hz for TNC mode --bw Hz Bandwidth in Hz for TNC mode --txp dBm TX power in dBm for TNC mode --sf factor Spreading factor for TNC mode (7 - 12) --cr rate Coding rate for TNC mode (5 - 8) -x, --ia-enable Enable interference avoidance -X, --ia-disable Disable interference avoidance -c, --config Print device configuration --eeprom-backup Backup EEPROM to file --eeprom-dump Dump EEPROM to console --eeprom-wipe Unlock and wipe EEPROM -P, --public Display public part of signing key --trust-key hexbytes Public key to trust for device verification --version Print program version and exit -f, --flash Flash firmware and bootstrap EEPROM -r, --rom Bootstrap EEPROM without flashing firmware -k, --key Generate a new signing key and exit -S, --sign Display public part of signing key -H, --firmware-hash FIRMWARE_HASH Set installed firmware hash --platform platform Platform specification for device bootstrap --product product Product specification for device bootstrap --model model Model code for device bootstrap --hwrev revision Hardware revision for device bootstrap ``` -------------------------------- ### Configure Release Permissions Source: https://reticulum.network/manual/git.html Manage release permissions using the `.allowed` file or configuration. Use `rel:target` syntax to grant or deny access for specific identities or everyone. ```bash # In .allowed file or config rel:all # Allow everyone rel:9710b86... # Allow specific identity rel:none # Deny everyone ``` -------------------------------- ### rnsh Command-Line Options Help Source: https://reticulum.network/manual/using.html Displays the usage information and all available command-line options for the rnsh utility. ```bash usage: rnsh [-h] [--config CONFIG] [--identity IDENTITY] [-v] [-q] [-p] [--version] [-l] [-s SERVICE] [-b PERIOD] [-a HASH] [-n] [-A] [-C] [-N] [-m] [-w SECONDS] [destination] Reticulum Remote Shell Utility positional arguments: destination hexadecimal hash of the destination to connect to options: -h, --help show this help message and exit --config, -c CONFIG path to alternative Reticulum config directory --identity, -i IDENTITY path to identity file to use -v, --verbose increase verbosity -q, --quiet decrease verbosity -p, --print-identity print identity and destination info and exit --version show program's version number and exit -l, --listen listen (server) mode; any command specified after -- will be used as the default command when the initiator does not provide one or when remote command execution is disabled; if no command is specified, the default shell of the user running rnsh will be used -s, --service SERVICE service name for identity file if not the default -b, --announce PERIOD announce on startup and every PERIOD seconds; specify 0 to announce on startup only -a, --allowed HASH allow this identity to connect (may be specified multiple times); allowed identities can also be specified in ~/.rnsh/allowed_identities or ~/.config/rnsh/allowed_identities, one hash per line -n, --no-auth disable authentication (allow any identity to connect) -A, --remote-command-as-args concatenate remote command to the argument list of the default program or shell -C, --no-remote-command disable executing command lines received from the remote initiator -N, --no-id disable identity announcement on connect -m, --mirror return with the exit code of the remote process -w, --timeout SECONDS connect and request timeout in seconds When specifying a command to execute, separate rnsh options from the command and its arguments with --. For example: rnsh -l -- /bin/bash --login rnsh -- ls -la /tmp ``` -------------------------------- ### rncp: Command-line options Source: https://reticulum.network/manual/using.html Displays all available command-line options for the rncp utility, including file transfer, listener, and configuration settings. ```bash usage: rncp [-h] [--config path] [-v] [-q] [-S] [-l] [-F] [-f] [-j path] [-b seconds] [-a allowed_hash] [-n] [-p] [-i identity] [-w seconds] [--version] [file] [destination] Reticulum File Transfer Utility positional arguments: file file to be transferred destination hexadecimal hash of the receiver options: -h, --help show this help message and exit --config path path to alternative Reticulum config directory -v, --verbose increase verbosity -q, --quiet decrease verbosity -S, --silent disable transfer progress output -l, --listen listen for incoming transfer requests -C, --no-compress disable automatic compression -F, --allow-fetch allow authenticated clients to fetch files -f, --fetch fetch file from remote listener instead of sending -j, --jail path restrict fetch requests to specified path -s, --save path save received files in specified path -O, --overwrite Allow overwriting received files, instead of adding postfix -b seconds announce interval, 0 to only announce at startup -a allowed_hash allow this identity (or add in ~/.rncp/allowed_identities) -n, --no-auth accept requests from anyone -p, --print-identity print identity and destination info and exit -i identity path to identity to use -w seconds sender timeout before giving up -P, --phy-rates display physical layer transfer rates --version show program's version number and exit ``` -------------------------------- ### Handle Client Connection and Disconnection Source: https://reticulum.network/manual/examples.html Callback functions for handling client link establishment and closure. Sets a global variable for the latest client link and logs connection events. ```python # When a client establishes a link to our server # destination, this function will be called with # a reference to the link. def client_connected(link): global latest_client_link RNS.log("Client connected") link.set_link_closed_callback(client_disconnected) latest_client_link = link def client_disconnected(link): RNS.log("Client disconnected") ``` -------------------------------- ### Install LXMF Module Source: https://reticulum.network/manual/interfaces.html Install the LXMF module using pip to enable Reticulum's interface discovery functionality. This module is required for publishing and discovering local interfaces on the network. ```bash pip install lxmf ``` -------------------------------- ### rngit Release Command-Line Options Source: https://reticulum.network/manual/git.html Displays the usage and available options for the `rngit release` subcommand, including arguments for repository, operation, and target, as well as various optional flags. ```bash usage: rngit release [-h] [--config CONFIG] [--rnsconfig RNSCONFIG] [-i PATH] [-v] [-q] [--version] [repository] [operation] [target] Reticulum Git Release Manager positional arguments: repository URL of remote repository operation list, view, create or delete target tag and path to release artifacts directory options: -h, --help show this help message and exit --config CONFIG path to alternative config directory --rnsconfig RNSCONFIG path to alternative Reticulum config directory -i, --identity PATH path to release identity -v, --verbose -q, --quiet --version show program's version number and exit ``` -------------------------------- ### Install Reticulum dependencies on Raspberry Pi Source: https://reticulum.network/manual/gettingstartedfast.html Install required dependencies for Reticulum on Raspberry Pi OS using apt. Ensure you are using a 64-bit OS for better package availability. ```bash # Install dependencies sudo apt install python3 python3-pip python3-cryptography python3-pyserial ``` -------------------------------- ### Announce Server Destination and Handle Input Source: https://reticulum.network/manual/examples.html Logs the server's destination hash and enters a loop that waits for user input. Pressing Enter sends an announcement for the server's destination on the network, making it discoverable by clients. Pressing Ctrl-C will quit the loop. ```python import RNS def announceLoop(destination): RNS.log( "Echo server "+ RNS.prettyhexrep(destination.hash)+ " running, hit enter to manually send an announce (Ctrl-C to quit)" ) while True: entered = input() destination.announce() RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash)) ``` -------------------------------- ### Install Reticulum on macOS using pip Source: https://reticulum.network/manual/gettingstartedfast.html Use this command to install Reticulum and its utilities on macOS systems with Python and pip available. The `--break-system-packages` flag may be necessary on some systems. ```bash pip3 install rns ``` ```bash # On some versions, you may need to use the # flag --break-system-packages to install: pip3 install rns --break-system-packages ``` -------------------------------- ### Client: Initialize Reticulum and Connect to Server Source: https://reticulum.network/manual/examples.html Initializes the Reticulum network, creates a client identity, and establishes a link to a specified server destination. Handles path discovery and logging connection status. ```python # A reference to the server link server_link = None # A reference to the client identity client_identity = None # This initialisation is executed when the users chooses # to run as a client def client(destination_hexhash, configpath): global client_identity # We need a binary representation of the destination # hash that was entered on the command line try: dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2 if len(destination_hexhash) != dest_len: raise ValueError( "Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).\n".format(hex=dest_len, byte=dest_len//2) ) destination_hash = bytes.fromhex(destination_hexhash) except: RNS.log("Invalid destination entered. Check your input!\n") sys.exit(0) # We must first initialise Reticulum reticulum = RNS.Reticulum(configpath) # Create a new client identity client_identity = RNS.Identity() RNS.log( "Client created new identity "+ str(client_identity) ) # Check if we know a path to the destination if not RNS.Transport.has_path(destination_hash): RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...") RNS.Transport.request_path(destination_hash) while not RNS.Transport.has_path(destination_hash): time.sleep(0.1) # Recall the server identity server_identity = RNS.Identity.recall(destination_hash) # Inform the user that we'll begin connecting RNS.log("Establishing link with server...") # When the server identity is known, we set # up a destination server_destination = RNS.Destination( server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "identifyexample" ) # And create a link link = RNS.Link(server_destination) # We set a callback that will get executed # every time a packet is received over the # link link.set_packet_callback(client_packet_received) # We'll also set up functions to inform the # user when the link is established or closed link.set_link_established_callback(link_established) link.set_link_closed_callback(link_closed) # Everything is set up, so let's enter a loop # for the user to interact with the example client_loop() ``` -------------------------------- ### Configure Pip to Allow System-Wide Installation Source: https://reticulum.network/manual/gettingstartedfast.html Alternatively, to restore normal pip behavior on Debian Bookworm and later, create or edit the pip configuration file to allow system-wide package installations. ```ini [global] break-system-packages = true ```