2021-09-24 03:17:23 -06:00
#!/usr/bin/env python3
2022-04-01 09:18:18 -06:00
# MIT License
#
# Copyright (c) 2016-2022 Mark Qvist / unsigned.io
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
2021-09-24 03:17:23 -06:00
import RNS
import argparse
2021-12-05 08:05:43 -07:00
import time
2021-09-24 03:17:23 -06:00
from RNS . _version import __version__
2021-12-05 08:05:43 -07:00
def program_setup ( configdir , verbosity = 0 , quietness = 0 , service = False ) :
2023-05-02 08:42:04 -06:00
targetverbosity = verbosity - quietness
2021-12-05 08:05:43 -07:00
if service :
2022-09-14 08:21:34 -06:00
targetlogdest = RNS . LOG_FILE
2023-05-02 08:42:04 -06:00
targetverbosity = None
2022-09-14 08:21:34 -06:00
else :
targetlogdest = RNS . LOG_STDOUT
2021-12-05 08:05:43 -07:00
2023-05-02 08:42:04 -06:00
reticulum = RNS . Reticulum ( configdir = configdir , verbosity = targetverbosity , logdest = targetlogdest )
2022-09-13 16:13:20 -06:00
if reticulum . is_connected_to_shared_instance :
RNS . log ( " Started rnsd version {version} connected to another shared local instance, this is probably NOT what you want! " . format ( version = __version__ ) , RNS . LOG_WARNING )
else :
RNS . log ( " Started rnsd version {version} " . format ( version = __version__ ) , RNS . LOG_NOTICE )
2021-09-24 03:17:23 -06:00
while True :
2021-12-05 08:05:43 -07:00
time . sleep ( 1 )
2021-09-24 03:17:23 -06:00
def main ( ) :
try :
2021-09-24 03:26:29 -06:00
parser = argparse . ArgumentParser ( description = " Reticulum Network Stack Daemon " )
2021-09-24 03:17:23 -06:00
parser . add_argument ( " --config " , action = " store " , default = None , help = " path to alternative Reticulum config directory " , type = str )
2021-09-24 12:05:24 -06:00
parser . add_argument ( ' -v ' , ' --verbose ' , action = ' count ' , default = 0 )
parser . add_argument ( ' -q ' , ' --quiet ' , action = ' count ' , default = 0 )
2021-12-05 08:05:43 -07:00
parser . add_argument ( ' -s ' , ' --service ' , action = ' store_true ' , default = False , help = " rnsd is running as a service and should log to file " )
2022-02-25 13:41:24 -07:00
parser . add_argument ( " --exampleconfig " , action = ' store_true ' , default = False , help = " print verbose configuration example to stdout and exit " )
2021-09-24 03:17:23 -06:00
parser . add_argument ( " --version " , action = " version " , version = " rnsd {version} " . format ( version = __version__ ) )
args = parser . parse_args ( )
2022-02-25 13:41:24 -07:00
if args . exampleconfig :
print ( __example_rns_config__ )
exit ( )
2021-09-24 03:17:23 -06:00
if args . config :
configarg = args . config
else :
configarg = None
2021-12-05 08:05:43 -07:00
program_setup ( configdir = configarg , verbosity = args . verbose , quietness = args . quiet , service = args . service )
2021-09-24 03:17:23 -06:00
except KeyboardInterrupt :
print ( " " )
exit ( )
2022-02-25 13:41:24 -07:00
__example_rns_config__ = ''' # This is an example Reticulum config file.
# You should probably edit it to include any additional,
# interfaces and settings you might need.
[ reticulum ]
# If you enable Transport, your system will route traffic
# for other peers, pass announces and serve path requests.
# This should be done for systems that are suited to act
# as transport nodes, ie. if they are stationary and
# always-on. This directive is optional and can be removed
# for brevity.
2023-09-21 10:33:14 -06:00
enable_transport = No
2022-02-25 13:41:24 -07:00
# By default, the first program to launch the Reticulum
# Network Stack will create a shared instance, that other
# programs can communicate with. Only the shared instance
# opens all the configured interfaces directly, and other
# local programs communicate with the shared instance over
# a local socket. This is completely transparent to the
# user, and should generally be turned on. This directive
# is optional and can be removed for brevity.
share_instance = Yes
# If you want to run multiple *different* shared instances
# on the same system, you will need to specify different
# shared instance ports for each. The defaults are given
# below, and again, these options can be left out if you
# don't need them.
shared_instance_port = 37428
instance_control_port = 37429
2023-09-21 10:33:14 -06:00
2023-10-07 04:40:30 -06:00
# On systems where running instances may not have access
# to the same shared Reticulum configuration directory,
# it is still possible to allow full interactivity for
# running instances, by manually specifying a shared RPC
# key. In almost all cases, this option is not needed, but
# it can be useful on operating systems such as Android.
# The key must be specified as bytes in hexadecimal.
# rpc_key = e5c032d3ec4e64a6aca9927ba8ab73336780f6d71790
2024-08-29 08:50:05 -06:00
# It is possible to allow remote management of Reticulum
# systems using the various built-in utilities, such as
# rnstatus and rnpath. You will need to specify one or
# more Reticulum Identity hashes for authenticating the
# queries from client programs. For this purpose, you can
# use existing identity files, or generate new ones with
# the rnid utility.
# enable_remote_management = yes
# remote_management_allowed = 9fb6d773498fb3feda407ed8ef2c3229, 2d882c5586e548d79b5af27bca1776dc
2022-02-25 13:41:24 -07:00
# You can configure Reticulum to panic and forcibly close
# if an unrecoverable interface error occurs, such as the
# hardware device for an interface disappearing. This is
# an optional directive, and can be left out for brevity.
# This behaviour is disabled by default.
panic_on_interface_error = No
2023-09-21 10:33:14 -06:00
# When Transport is enabled, it is possible to allow the
# Transport Instance to respond to probe requests from
# the rnprobe utility. This can be a useful tool to test
# connectivity. When this option is enabled, the probe
# destination will be generated from the Identity of the
# Transport Instance, and printed to the log at startup.
# Optional, and disabled by default.
respond_to_probes = No
2022-02-25 13:41:24 -07:00
[ logging ]
# Valid log levels are 0 through 7:
# 0: Log only critical information
# 1: Log errors and lower log levels
# 2: Log warnings and lower log levels
# 3: Log notices and lower log levels
# 4: Log info and lower (this is the default)
# 5: Verbose logging
# 6: Debug logging
# 7: Extreme logging
loglevel = 4
# The interfaces section defines the physical and virtual
# interfaces Reticulum will use to communicate on. This
# section will contain examples for a variety of interface
# types. You can modify these or use them as a basis for
# your own config, or simply remove the unused ones.
[ interfaces ]
# This interface enables communication with other
# link-local Reticulum nodes over UDP. It does not
# need any functional IP infrastructure like routers
# or DHCP servers, but will require that at least link-
# local IPv6 is enabled in your operating system, which
# should be enabled by default in almost any OS. See
# the Reticulum Manual for more configuration options.
[ [ Default Interface ] ]
type = AutoInterface
2022-05-25 15:10:05 -06:00
enabled = yes
2022-02-25 13:41:24 -07:00
# The following example enables communication with other
# local Reticulum peers using UDP broadcasts.
[ [ UDP Interface ] ]
type = UDPInterface
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-25 13:41:24 -07:00
listen_ip = 0.0 .0 .0
listen_port = 4242
forward_ip = 255.255 .255 .255
forward_port = 4242
# The above configuration will allow communication
# within the local broadcast domains of all local
# IP interfaces.
# Instead of specifying listen_ip, listen_port,
# forward_ip and forward_port, you can also bind
# to a specific network device like below.
# device = eth0
# port = 4242
# Assuming the eth0 device has the address
# 10.55.0.72/24, the above configuration would
# be equivalent to the following manual setup.
# Note that we are both listening and forwarding to
# the broadcast address of the network segments.
# listen_ip = 10.55.0.255
# listen_port = 4242
# forward_ip = 10.55.0.255
# forward_port = 4242
# You can of course also communicate only with
# a single IP address
# listen_ip = 10.55.0.15
# listen_port = 4242
# forward_ip = 10.55.0.16
# forward_port = 4242
# This example demonstrates a TCP server interface.
# It will listen for incoming connections on the
# specified IP address and port number.
[ [ TCP Server Interface ] ]
type = TCPServerInterface
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-25 13:41:24 -07:00
# This configuration will listen on all IP
# interfaces on port 4242
listen_ip = 0.0 .0 .0
listen_port = 4242
# Alternatively you can bind to a specific IP
# listen_ip = 10.0.0.88
# listen_port = 4242
# Or a specific network device
# device = eth0
# port = 4242
# To connect to a TCP server interface, you would
# naturally use the TCP client interface. Here's
# an example. The target_host can either be an IP
# address or a hostname
[ [ TCP Client Interface ] ]
type = TCPClientInterface
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-25 13:41:24 -07:00
target_host = 127.0 .0 .1
target_port = 4242
# This example shows how to make your Reticulum
# instance available over I2P, and connect to
# another I2P peer. Please be aware that you
# must have an I2P router running on your system
# with the SAMv3 API enabled for this to work.
[ [ I2P ] ]
type = I2PInterface
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-26 13:04:54 -07:00
connectable = yes
2022-05-25 15:10:05 -06:00
peers = ykzlw5ujbaqc2xkec4cpvgyxj257wcrmmgkuxqmqcur7cq3w3lha . b32 . i2p
2022-02-25 13:41:24 -07:00
# Here's an example of how to add a LoRa interface
# using the RNode LoRa transceiver.
[ [ RNode LoRa Interface ] ]
type = RNodeInterface
# Enable interface if you want use it!
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-25 13:41:24 -07:00
# Serial port for the device
port = / dev / ttyUSB0
2024-10-01 18:05:00 -06:00
# It is also possible to use BLE devices
# instead of wired serial ports. The
# target RNode must be paired with the
# host device before connecting. BLE
# devices can be connected by name,
# BLE MAC address or by any available.
# Connect to specific device by name
# port = ble://RNode 3B87
# Or by BLE MAC address
# port = ble://F4:12:73:29:4E:89
# Or connect to the first available,
# paired device
# port = ble://
2022-02-25 13:41:24 -07:00
# Set frequency to 867.2 MHz
frequency = 867200000
# Set LoRa bandwidth to 125 KHz
bandwidth = 125000
# Set TX power to 7 dBm (5 mW)
txpower = 7
# Select spreading factor 8. Valid
# range is 7 through 12, with 7
# being the fastest and 12 having
# the longest range.
spreadingfactor = 8
# Select coding rate 5. Valid range
# is 5 throough 8, with 5 being the
# fastest, and 8 the longest range.
codingrate = 5
# You can configure the RNode to send
# out identification on the channel with
# a set interval by configuring the
# following two parameters. The trans-
# ceiver will only ID if the set
# interval has elapsed since it's last
# actual transmission. The interval is
# configured in seconds.
# This option is commented out and not
# used by default.
# id_callsign = MYCALL-0
# id_interval = 600
# For certain homebrew RNode interfaces
# with low amounts of RAM, using packet
# flow control can be useful. By default
# it is disabled.
flow_control = False
# An example KISS modem interface. Useful for running
# Reticulum over packet radio hardware.
[ [ Packet Radio KISS Interface ] ]
type = KISSInterface
# Enable interface if you want use it!
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-25 13:41:24 -07:00
# Serial port for the device
port = / dev / ttyUSB1
# Set the serial baud-rate and other
# configuration parameters.
speed = 115200
databits = 8
parity = none
stopbits = 1
# Set the modem preamble. A 150ms
# preamble should be a reasonable
# default, but may need to be
# increased for radios with slow-
# opening squelch and long TX/RX
# turnaround
preamble = 150
# Set the modem TX tail. In most
# cases this should be kept as low
# as possible to not waste airtime.
txtail = 10
# Configure CDMA parameters. These
# settings are reasonable defaults.
persistence = 200
slottime = 20
# You can configure the interface to send
# out identification on the channel with
# a set interval by configuring the
# following two parameters. The KISS
# interface will only ID if the set
# interval has elapsed since it's last
# actual transmission. The interval is
# configured in seconds.
# This option is commented out and not
# used by default.
# id_callsign = MYCALL-0
# id_interval = 600
# Whether to use KISS flow-control.
# This is useful for modems that have
# a small internal packet buffer, but
# support packet flow control instead.
flow_control = false
# If you're using Reticulum on amateur radio spectrum,
# you might want to use the AX.25 KISS interface. This
# way, Reticulum will automatically encapsulate it's
# traffic in AX.25 and also identify your stations
# transmissions with your callsign and SSID.
#
# Only do this if you really need to! Reticulum doesn't
# need the AX.25 layer for anything, and it incurs extra
# overhead on every packet to encapsulate in AX.25.
#
# A more efficient way is to use the plain KISS interface
# with the beaconing functionality described above.
[ [ Packet Radio AX .25 KISS Interface ] ]
type = AX25KISSInterface
# Set the station callsign and SSID
callsign = NO1CLL
ssid = 0
# Enable interface if you want use it!
2022-05-25 15:10:05 -06:00
enabled = no
2022-02-25 13:41:24 -07:00
# Serial port for the device
port = / dev / ttyUSB2
# Set the serial baud-rate and other
# configuration parameters.
speed = 115200
databits = 8
parity = none
stopbits = 1
# Whether to use KISS flow-control.
# This is useful for modems with a
# small internal packet buffer.
flow_control = false
# Set the modem preamble. A 150ms
# preamble should be a reasonable
# default, but may need to be
# increased for radios with slow-
# opening squelch and long TX/RX
# turnaround
preamble = 150
# Set the modem TX tail. In most
# cases this should be kept as low
# as possible to not waste airtime.
txtail = 10
# Configure CDMA parameters. These
# settings are reasonable defaults.
persistence = 200
slottime = 20
'''
2021-09-24 03:17:23 -06:00
if __name__ == " __main__ " :
2022-02-25 13:41:24 -07:00
main ( )