Compare commits

...

54 Commits

Author SHA1 Message Date
Mark Qvist c5687f190b Updated manual 2024-10-06 10:49:56 +02:00
Mark Qvist 44d1f6d0e5 Updated changelog 2024-10-06 10:49:48 +02:00
Mark Qvist ac09bc3567 Updated manual 2024-10-06 10:28:26 +02:00
Mark Qvist a41bce012b Fix docs images for PDF generation 2024-10-06 10:27:27 +02:00
Mark Qvist 83a2999d29 Revert AF_INET6 addition to TCPInterface, since it breaks normal IPv4 connectivity for interface 2024-10-06 10:01:55 +02:00
markqvist 4465fa9882 Merge pull request #545 from deavmi/master
Support IPv6 for outbound TCP interface (TCPClientInterface)
2024-10-05 23:46:28 +02:00
Mark Qvist ce974db084 Merge branch 'master' of github.com:markqvist/Reticulum 2024-10-05 23:45:48 +02:00
markqvist e6c1dc075b Merge pull request #556 from jacobeva/rnode-multi-fix
Fix interface values not being set on RNodeSubInterface instances
2024-10-05 23:45:21 +02:00
Mark Qvist 9602f67b06 Merge branch 'master' of github.com:markqvist/Reticulum 2024-10-05 23:44:17 +02:00
markqvist ef798e0d54 Merge pull request #543 from jacobeva/display-fix
Allow for use of display by master on NRF52
2024-10-05 23:43:56 +02:00
Mark Qvist 5cd8d229fb Updated manual 2024-10-05 23:43:28 +02:00
Mark Qvist d4808b7ff1 Added supported boards to manual 2024-10-05 23:43:02 +02:00
markqvist 3dc8729e70 Merge pull request #565 from jacobeva/framing-fix
Fix RNodeMultiInterface interface framing
2024-10-05 23:03:36 +02:00
markqvist f500a063dc Merge pull request #564 from prusnak/docs-hardware
docs: add Heltec LoRa32 v3.0 and LilyGO LoRa32 v1.0 to hardware
2024-10-05 23:00:43 +02:00
Mark Qvist eca1e53b55 Added support for T-Beam Supreme, T-Deck and T3S3 devices with SX127X chips to rnodeconf 2024-10-05 22:29:31 +02:00
Mark Qvist 53226d7035 Cap resource max window for resource transfer over very slow links 2024-10-05 20:54:42 +02:00
Mark Qvist 7363c9c821 Increase PATH_REQUEST_RG to 1.5 seconds 2024-10-05 19:20:48 +02:00
Mark Qvist bb8b8b4f81 Added handling for receiving a link proof after the link had timed out and been closed, but before it having been purged from active links table 2024-10-05 18:43:56 +02:00
Mark Qvist 0f0f459321 Updated version 2024-10-05 17:05:41 +02:00
Mark Qvist df887f6d63 Added product and model code defines for new boards to rnodeconf 2024-10-05 17:05:34 +02:00
Mark Qvist b526e3554c Added low memory error decsription to RNodeInterface 2024-10-05 17:05:02 +02:00
Mark Qvist 903ab53fc9 Fixed init fail due to missing library on Android/Termux 2024-10-05 17:04:39 +02:00
Mark Qvist f461a7827b Added T-Deck defines to rnodeconf 2024-10-03 00:52:38 +02:00
Mark Qvist 62091b28b0 Fixed version comparison 2024-10-02 02:54:18 +02:00
Mark Qvist 48045856bf Updated changelog 2024-10-02 02:09:41 +02:00
Mark Qvist 6ba5efcb42 Updated documentation 2024-10-02 02:08:41 +02:00
Mark Qvist a505441b98 Added BLE connection config to docs 2024-10-02 02:05:00 +02:00
Mark Qvist 976e5543e1 Updated changelog 2024-10-02 01:58:35 +02:00
Mark Qvist fcc7b50ac6 Updated docs 2024-10-01 23:53:53 +02:00
Mark Qvist 72971d1aef Handle RNode BLE MTU request errors 2024-10-01 23:52:04 +02:00
Mark Qvist 9a8d46ab21 Updated version 2024-10-01 17:28:40 +02:00
Mark Qvist 8adab7ee7d Added BLE support to Android RNodeInterface 2024-10-01 17:27:45 +02:00
Mark Qvist b5bde99322 Added RNode battery info to rnstatus output 2024-10-01 17:25:44 +02:00
Mark Qvist 560c8e164c Added BLE support to RNodeInterface 2024-10-01 17:25:16 +02:00
jacob.eva e059363f1d Version bump for CE firmware version which will contain framing change 2024-10-01 16:02:07 +01:00
jacob.eva 4930477b99 Fix interface framing assignment conflict 2024-10-01 15:58:27 +01:00
Mark Qvist 312489e4dc Added BLE config support to RNodeInterface 2024-09-30 19:09:35 +02:00
Pavol Rusnak 43d8fdb423 docs: add Heltec LoRa32 v3.0 and LilyGO LoRa32 v1.0 to hardware 2024-09-29 11:51:43 +02:00
Mark Qvist 1c56385473 Added display blanking timeout configuration to rnodeconf 2024-09-29 02:35:44 +02:00
Mark Qvist 787af92ade Added option to configure NeoPixel intensity to rnodeconf 2024-09-27 20:07:04 +02:00
Mark Qvist 131dbd2813 Updated changelog 2024-09-25 13:26:23 +02:00
Mark Qvist 9df81ce365 Updated manual 2024-09-25 13:25:43 +02:00
Mark Qvist 490a56450a Updated changelog 2024-09-25 13:23:15 +02:00
Mark Qvist 52a5156304 Cleanup 2024-09-25 13:20:41 +02:00
Mark Qvist 538e7320fd Updated docs 2024-09-25 13:17:03 +02:00
Mark Qvist 2d351a59e9 Updated version 2024-09-25 13:11:17 +02:00
Mark Qvist 2269d6cef9 Updated readme 2024-09-25 13:06:31 +02:00
Mark Qvist 813edc8b17 Updated readme 2024-09-25 13:04:23 +02:00
Mark Qvist 099e344996 Updated roadmap 2024-09-25 12:43:40 +02:00
Mark Qvist 42319a092d Added additional information to interface stats 2024-09-24 20:26:15 +02:00
jacob.eva 9a97195b8c Fix interface values not being set on RNodeSubInterface instances 2024-09-20 17:50:34 +01:00
Tristan Brice Velloza Kildaire 5c6ee07d66 TCPInterface
- When connect(s, Bool)` is called construct a socket that supports both address families
2024-09-05 00:07:35 +02:00
jacob.eva 9d744e2317 Allow for display use by master on NRF52 on Android 2024-09-04 11:54:32 +01:00
jacob.eva d64064691a Allow for use of display by master on NRF52 2024-09-04 11:52:41 +01:00
60 changed files with 1582 additions and 352 deletions
+58
View File
@@ -1,3 +1,61 @@
### 2024-10-06: RNS β 0.8.2
This release adds several new boards to `rnodeconf`, fixes a range of bugs and improves transport reliability.
Thanks to @jacobeva, @prusnak and @deavmi who contributed to this release!
**Changes**
- Added support for T-Beam Supreme devices to `rnodeconf`
- Added support for T3S3 devices to `rnodeconf`
- Added support for T-Deck devices to `rnodeconf`
- Added support for new hardware error codes from connected RNodes
- Added the ability to control the display on nRF52-based RNodes
- Improved resource transfers over very slow links, by adding more suitable `MAX_WINDOW` cap if link speed is continously below threshold.
- Improved `rnodeconf` flashing so manual resets for some devices are no longer required
- Added edge case handling for receiving a link proof after the link had timed out and been closed, but before it having been purged from active links table
- Updated supported hardware section of the manual with new boards
- Tuned path request timing for roaming instances
- Fixed a bug that caused RNS to fail to initialise in Termux on Android
- Fixed a bug in RNodeInterface firmware version comparison
- Fixed a bug in the serial framing of RNodeMultiInterface
- Fixed a bug in sub-interface spawning of RNodeMultiInterface
**Release Hashes**
```
db720a727a09c0c9d76288dec5a995a30146e65d6a4c5c034f47fb60a78f4962 rns-0.8.2-py3-none-any.whl
ee412535edba48817551658247fb0c843d17e1c97cad9d2a819a7fc627c5ba28 rnspure-0.8.2-py3-none-any.whl
```
### 2024-10-02: RNS β 0.8.1
This release adds BLE support to RNodeInterface, and support for configuring additional options to `rnodeconf`.
**Changes**
- Added Bluetooth Low Energy support to RNodeInterface
- Added RNode battery information to `rnstatus` output
- Added display blanking configuration to `rnodeconf`
- Added NeoPixel intensity configuration to `rnodeconf`
**Release Hashes**
```
f4b6b99b67d6b33b8a4562e5d5d5ac54c76814fff26e6c7a79950b82bd80123f rns-0.8.1-py3-none-any.whl
c2e540b4bf0f272bb51ae3e33a02f9c07f2619746d069d7ed83d88017bf7ea30 rnspure-0.8.1-py3-none-any.whl
```
### 2024-09-25: RNS β 0.8.0
This maintenance release improves the interface statistics API, and updates documentation.
**Changes**
- Added additional information to interface statistics
- Updated documentation
**Release Hashes**
```
fa5ff6d98230693be6805bb9a94585a6f54ec0af9cba15b771d4e676f140dc43 rns-0.8.0-py3-none-any.whl
ba20f688b69ae861c8aced251e10242a358fea15da6c22df10d4fc8846c9bf48 rnspure-0.8.0-py3-none-any.whl
```
### 2024-09-24: RNS β 0.7.9
This maintenance release improves transport reliability in certain (rare) cases.
+13 -10
View File
@@ -41,21 +41,23 @@ For more info, see [reticulum.network](https://reticulum.network/) and [the FAQ
## Notable Features
- Coordination-less globally unique addressing and identification
- Fully self-configuring multi-hop routing
- Fully self-configuring multi-hop routing over heterogeneous carriers
- Initiator anonymity, communicate without revealing your identity
- Reticulum does not include source addresses on any packets
- Asymmetric X25519 encryption and Ed25519 signatures as a basis for all communication
- Forward Secrecy with ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519
- The foundational Reticulum Identity Keys are 512-bit Elliptic Curve keysets
- Forward Secrecy is available for all communication types, both for single packets and over links
- Reticulum uses the following format for encrypted tokens:
- Keys are ephemeral and derived from an ECDH key exchange on Curve25519
- Ephemeral per-packet and link keys and derived from an ECDH key exchange on Curve25519
- AES-128 in CBC mode with PKCS7 padding
- HMAC using SHA256 for authentication
- IVs are generated through os.urandom()
- Unforgeable packet delivery confirmations
- A variety of supported interface types
- A large variety of supported interface types
- An intuitive and easy-to-use API
- Reliable and efficient transfer of arbitrary amounts of data
- Reticulum can handle a few bytes of data or files of many gigabytes
- Sequencing, transfer coordination and checksumming are automatic
- Sequencing, compression, transfer coordination and checksumming are automatic
- The API is very easy to use, and provides transfer progress
- Lightweight, flexible and expandable Request/Response mechanism
- Efficient link establishment
@@ -298,14 +300,15 @@ Are certain features in the development roadmap are important to you or your
organisation? Make them a reality quickly by sponsoring their implementation.
## Cryptographic Primitives
Reticulum uses a simple suite of efficient, strong and modern cryptographic
Reticulum uses a simple suite of efficient, strong and well-tested cryptographic
primitives, with widely available implementations that can be used both on
general-purpose CPUs and on microcontrollers. The necessary primitives are:
general-purpose CPUs and on microcontrollers. The utilised primitives are:
- Ed25519 for signatures
- X22519 for ECDH key exchanges
- Reticulum Identity Keys are 512-bit Curve25519 keysets
- A 256-bit Ed25519 key for signatures
- A 256-bit X22519 key for ECDH key exchanges
- HKDF for key derivation
- Modified Fernet for encrypted tokens
- Encrypted tokens are based on the [Fernet spec](https://github.com/fernet/spec/)
- Ephemeral keys derived from an ECDH key exchange on Curve25519
- AES-128 in CBC mode with PKCS7 padding
- HMAC using SHA256 for message authentication
+472 -100
View File
@@ -28,6 +28,15 @@ import time
import math
import RNS
try:
from able import BluetoothDispatcher, GATT_SUCCESS
except Exception as e:
GATT_SUCCESS = 0x00
class BluetoothDispatcher():
def __init__(**kwargs):
RNS.log("Attempt to initialise BLE connectivity, but Android BLE support library is unavailable", RNS.LOG_ERROR)
raise OSError("No BLE support available")
class KISS():
FEND = 0xC0
FESC = 0xDB
@@ -54,6 +63,7 @@ class KISS():
CMD_STAT_SNR = 0x24
CMD_STAT_CHTM = 0x25
CMD_STAT_PHYPRM = 0x26
CMD_STAT_BAT = 0x27
CMD_BLINK = 0x30
CMD_RANDOM = 0x40
CMD_FB_EXT = 0x41
@@ -77,10 +87,14 @@ class KISS():
ERROR_INITRADIO = 0x01
ERROR_TXFAILED = 0x02
ERROR_EEPROM_LOCKED = 0x03
ERROR_QUEUE_FULL = 0x04
ERROR_MEMORY_LOW = 0x05
ERROR_INVALID_FIRMWARE = 0x10
ERROR_INVALID_BLE_MTU = 0x20
PLATFORM_AVR = 0x90
PLATFORM_ESP32 = 0x80
PLATFORM_NRF52 = 0x70
@staticmethod
def escape(data):
@@ -89,6 +103,10 @@ class KISS():
return data
class AndroidBluetoothManager():
DEVICE_TYPE_CLASSIC = 1
DEVICE_TYPE_LE = 2
DEVICE_TYPE_DUAL = 3
def __init__(self, owner, target_device_name = None, target_device_address = None):
from jnius import autoclass
self.owner = owner
@@ -237,6 +255,11 @@ class RNodeInterface(Interface):
Q_SNR_MAX = 6
Q_SNR_STEP = 2
BATTERY_STATE_UNKNOWN = 0x00
BATTERY_STATE_DISCHARGING = 0x01
BATTERY_STATE_CHARGING = 0x02
BATTERY_STATE_CHARGED = 0x03
@classmethod
def bluetooth_control(device_serial = None, port = None, enable_bluetooth = False, disable_bluetooth = False, pairing_mode = False):
if (port != None or device_serial != None) and (enable_bluetooth or disable_bluetooth or pairing_mode):
@@ -321,7 +344,8 @@ class RNodeInterface(Interface):
self, owner, name, port, frequency = None, bandwidth = None, txpower = None,
sf = None, cr = None, flow_control = False, id_interval = None,
allow_bluetooth = False, target_device_name = None,
target_device_address = None, id_callsign = None, st_alock = None, lt_alock = None):
target_device_address = None, id_callsign = None, st_alock = None, lt_alock = None,
ble_addr = None, ble_name = None, force_ble=False):
import importlib
if RNS.vendor.platformutils.is_android():
self.on_android = True
@@ -368,9 +392,19 @@ class RNodeInterface(Interface):
self.stopbits = 1
self.timeout = 150
self.online = False
self.detached = False
self.hw_errors = []
self.allow_bluetooth = allow_bluetooth
self.use_ble = False
self.ble_name = ble_name
self.ble_addr = ble_addr
self.ble = None
self.ble_rx_lock = threading.Lock()
self.ble_tx_lock = threading.Lock()
self.ble_rx_queue= b""
self.ble_tx_queue= b""
self.frequency = frequency
self.bandwidth = bandwidth
self.txpower = txpower
@@ -391,6 +425,7 @@ class RNodeInterface(Interface):
self.last_id = 0
self.first_tx = None
self.reconnect_w = RNodeInterface.RECONNECT_WAIT
self.reconnect_lock = threading.Lock()
self.r_frequency = None
self.r_bandwidth = None
@@ -414,6 +449,8 @@ class RNodeInterface(Interface):
self.r_symbol_rate = None
self.r_preamble_symbols = None
self.r_premable_time_ms = None
self.r_battery_state = RNodeInterface.BATTERY_STATE_UNKNOWN
self.r_battery_percent = 0
self.packet_queue = []
self.flow_control = flow_control
@@ -423,6 +460,9 @@ class RNodeInterface(Interface):
self.port_io_timeout = RNodeInterface.PORT_IO_TIMEOUT
self.last_imagedata = None
if force_ble or self.ble_addr != None or self.ble_name != None:
self.use_ble = True
self.validcfg = True
if (self.frequency < RNodeInterface.FREQ_MIN or self.frequency > RNodeInterface.FREQ_MAX):
RNS.log("Invalid frequency configured for "+str(self), RNS.LOG_ERROR)
@@ -488,9 +528,7 @@ class RNodeInterface(Interface):
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
if len(self.hw_errors) == 0:
RNS.log("Reticulum will attempt to bring up this interface periodically", RNS.LOG_ERROR)
thread = threading.Thread(target=self.reconnect_port)
thread.daemon = True
thread.start()
thread = threading.Thread(target=self.reconnect_port, daemon=True).start()
def read_mux(self, len=None):
@@ -514,88 +552,116 @@ class RNodeInterface(Interface):
else:
raise IOError("No ports available for writing")
# def reset_ble(self):
# RNS.log(f"Clearing previous connection instance: "+str(self.ble))
# del self.ble
# self.ble = None
# self.serial = None
# self.ble = BLEConnection(owner=self, target_name=self.ble_name, target_bt_addr=self.ble_addr)
# self.serial = self.ble
# RNS.log(f"New connection instance: "+str(self.ble))
def open_port(self):
if self.port != None:
RNS.log("Opening serial port "+self.port+"...")
# Get device parameters
from usb4a import usb
device = usb.get_usb_device(self.port)
if device:
vid = device.getVendorId()
pid = device.getProductId()
if not self.use_ble:
if self.port != None:
RNS.log("Opening serial port "+self.port+"...")
# Get device parameters
from usb4a import usb
device = usb.get_usb_device(self.port)
if device:
vid = device.getVendorId()
pid = device.getProductId()
# Driver overrides for speficic chips
proxy = self.pyserial.get_serial_port
if vid == 0x1A86 and pid == 0x55D4:
# Force CDC driver for Qinheng CH34x
RNS.log(str(self)+" using CDC driver for "+RNS.hexrep(vid)+":"+RNS.hexrep(pid), RNS.LOG_DEBUG)
from usbserial4a.cdcacmserial4a import CdcAcmSerial
proxy = CdcAcmSerial
# Driver overrides for speficic chips
proxy = self.pyserial.get_serial_port
if vid == 0x1A86 and pid == 0x55D4:
# Force CDC driver for Qinheng CH34x
RNS.log(str(self)+" using CDC driver for "+RNS.hexrep(vid)+":"+RNS.hexrep(pid), RNS.LOG_DEBUG)
from usbserial4a.cdcacmserial4a import CdcAcmSerial
proxy = CdcAcmSerial
self.serial = proxy(
self.port,
baudrate = self.speed,
bytesize = self.databits,
parity = self.parity,
stopbits = self.stopbits,
xonxoff = False,
rtscts = False,
timeout = None,
inter_byte_timeout = None,
# write_timeout = wtimeout,
dsrdtr = False,
)
self.serial = proxy(
self.port,
baudrate = self.speed,
bytesize = self.databits,
parity = self.parity,
stopbits = self.stopbits,
xonxoff = False,
rtscts = False,
timeout = None,
inter_byte_timeout = None,
# write_timeout = wtimeout,
dsrdtr = False,
)
if vid == 0x0403:
# Hardware parameters for FTDI devices @ 115200 baud
self.serial.DEFAULT_READ_BUFFER_SIZE = 16 * 1024
self.serial.USB_READ_TIMEOUT_MILLIS = 100
self.serial.timeout = 0.1
elif vid == 0x10C4:
# Hardware parameters for SiLabs CP210x @ 115200 baud
self.serial.DEFAULT_READ_BUFFER_SIZE = 64
self.serial.USB_READ_TIMEOUT_MILLIS = 12
self.serial.timeout = 0.012
elif vid == 0x1A86 and pid == 0x55D4:
# Hardware parameters for Qinheng CH34x @ 115200 baud
self.serial.DEFAULT_READ_BUFFER_SIZE = 64
self.serial.USB_READ_TIMEOUT_MILLIS = 12
self.serial.timeout = 0.1
else:
# Default values
self.serial.DEFAULT_READ_BUFFER_SIZE = 1 * 1024
self.serial.USB_READ_TIMEOUT_MILLIS = 100
self.serial.timeout = 0.1
if vid == 0x0403:
# Hardware parameters for FTDI devices @ 115200 baud
self.serial.DEFAULT_READ_BUFFER_SIZE = 16 * 1024
self.serial.USB_READ_TIMEOUT_MILLIS = 100
self.serial.timeout = 0.1
elif vid == 0x10C4:
# Hardware parameters for SiLabs CP210x @ 115200 baud
self.serial.DEFAULT_READ_BUFFER_SIZE = 64
self.serial.USB_READ_TIMEOUT_MILLIS = 12
self.serial.timeout = 0.012
elif vid == 0x1A86 and pid == 0x55D4:
# Hardware parameters for Qinheng CH34x @ 115200 baud
self.serial.DEFAULT_READ_BUFFER_SIZE = 64
self.serial.USB_READ_TIMEOUT_MILLIS = 12
self.serial.timeout = 0.1
else:
# Default values
self.serial.DEFAULT_READ_BUFFER_SIZE = 1 * 1024
self.serial.USB_READ_TIMEOUT_MILLIS = 100
self.serial.timeout = 0.1
RNS.log(str(self)+" USB read buffer size set to "+RNS.prettysize(self.serial.DEFAULT_READ_BUFFER_SIZE), RNS.LOG_DEBUG)
RNS.log(str(self)+" USB read timeout set to "+str(self.serial.USB_READ_TIMEOUT_MILLIS)+"ms", RNS.LOG_DEBUG)
RNS.log(str(self)+" USB write timeout set to "+str(self.serial.USB_WRITE_TIMEOUT_MILLIS)+"ms", RNS.LOG_DEBUG)
RNS.log(str(self)+" USB read buffer size set to "+RNS.prettysize(self.serial.DEFAULT_READ_BUFFER_SIZE), RNS.LOG_DEBUG)
RNS.log(str(self)+" USB read timeout set to "+str(self.serial.USB_READ_TIMEOUT_MILLIS)+"ms", RNS.LOG_DEBUG)
RNS.log(str(self)+" USB write timeout set to "+str(self.serial.USB_WRITE_TIMEOUT_MILLIS)+"ms", RNS.LOG_DEBUG)
elif self.allow_bluetooth:
if self.bt_manager == None:
self.bt_manager = AndroidBluetoothManager(
owner = self,
target_device_name = self.bt_target_device_name,
target_device_address = self.bt_target_device_address
)
elif self.allow_bluetooth:
if self.bt_manager == None:
self.bt_manager = AndroidBluetoothManager(
owner = self,
target_device_name = self.bt_target_device_name,
target_device_address = self.bt_target_device_address
)
if self.bt_manager != None:
self.bt_manager.connect_any_device()
if self.bt_manager != None:
self.bt_manager.connect_any_device()
else:
if self.ble == None:
self.ble = BLEConnection(owner=self, target_name=self.ble_name, target_bt_addr=self.ble_addr)
self.serial = self.ble
open_time = time.time()
while not self.ble.connected and time.time() < open_time + self.ble.CONNECT_TIMEOUT:
time.sleep(1)
def configure_device(self):
self.resetRadioState()
sleep(2.0)
thread = threading.Thread(target=self.readLoop)
thread.daemon = True
thread.start()
thread = threading.Thread(target=self.readLoop, daemon=True).start()
self.detect()
sleep(0.5)
if not self.use_ble:
sleep(0.5)
else:
ble_detect_timeout = 5
detect_time = time.time()
while not self.detected and time.time() < detect_time + ble_detect_timeout:
time.sleep(0.1)
if self.detected:
detect_time = RNS.prettytime(time.time()-detect_time)
else:
RNS.log(f"RNode detect timed out over {self.port}", RNS.LOG_ERROR)
if not self.detected:
raise IOError("Could not detect device")
else:
if self.platform == KISS.PLATFORM_ESP32:
if self.platform == KISS.PLATFORM_ESP32 or self.platform == KISS.PLATFORM_NRF52:
self.display = True
if not self.firmware_ok:
@@ -654,6 +720,9 @@ class RNodeInterface(Interface):
self.setRadioState(KISS.RADIO_STATE_ON)
time.sleep(0.15)
if self.use_ble:
time.sleep(1)
def detect(self):
kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND])
written = self.write_mux(kiss_command)
@@ -807,16 +876,19 @@ class RNodeInterface(Interface):
raise IOError("An IO error occurred while configuring radio state for "+str(self))
def validate_firmware(self):
if (self.maj_version >= RNodeInterface.REQUIRED_FW_VER_MAJ):
if (self.min_version >= RNodeInterface.REQUIRED_FW_VER_MIN):
self.firmware_ok = True
if (self.maj_version > RNodeInterface.REQUIRED_FW_VER_MAJ):
self.firmware_ok = True
else:
if (self.maj_version >= RNodeInterface.REQUIRED_FW_VER_MAJ):
if (self.min_version >= RNodeInterface.REQUIRED_FW_VER_MIN):
self.firmware_ok = True
if self.firmware_ok:
return
RNS.log("The firmware version of the connected RNode is "+str(self.maj_version)+"."+str(self.min_version), RNS.LOG_ERROR)
RNS.log("This version of Reticulum requires at least version "+str(RNodeInterface.REQUIRED_FW_VER_MAJ)+"."+str(RNodeInterface.REQUIRED_FW_VER_MIN), RNS.LOG_ERROR)
RNS.log("Please update your RNode firmware with rnodeconf from https://github.com/markqvist/rnodeconfigutil/")
RNS.log("Please update your RNode firmware with rnodeconf from https://github.com/markqvist/reticulum/")
error_description = "The firmware version of the connected RNode is "+str(self.maj_version)+"."+str(self.min_version)+". "
error_description += "This version of Reticulum requires at least version "+str(RNodeInterface.REQUIRED_FW_VER_MAJ)+"."+str(RNodeInterface.REQUIRED_FW_VER_MIN)+". "
error_description += "Please update your RNode firmware with rnodeconf from: https://github.com/markqvist/rnodeconfigutil/"
@@ -824,7 +896,7 @@ class RNodeInterface(Interface):
def validateRadioState(self):
RNS.log("Wating for radio configuration validation for "+str(self)+"...", RNS.LOG_VERBOSE)
RNS.log("Waiting for radio configuration validation for "+str(self)+"...", RNS.LOG_VERBOSE)
if not self.platform == KISS.PLATFORM_ESP32:
sleep(1.00);
else:
@@ -852,6 +924,13 @@ class RNodeInterface(Interface):
else:
return False
def resetRadioState(self):
self.r_frequency = None
self.r_bandwidth = None
self.r_txpower = None
self.r_sf = None
self.r_cr = None
self.r_state = None
def updateBitrate(self):
try:
@@ -1140,6 +1219,25 @@ class RNodeInterface(Interface):
RNS.log(str(self)+" Radio reporting symbol time is "+str(round(self.r_symbol_time_ms,2))+"ms (at "+str(self.r_symbol_rate)+" baud)", RNS.LOG_DEBUG)
RNS.log(str(self)+" Radio reporting preamble is "+str(self.r_preamble_symbols)+" symbols ("+str(self.r_premable_time_ms)+"ms)", RNS.LOG_DEBUG)
RNS.log(str(self)+" Radio reporting CSMA slot time is "+str(self.r_csma_slot_time_ms)+"ms", RNS.LOG_DEBUG)
elif (command == KISS.CMD_STAT_BAT):
if (byte == KISS.FESC):
escape = True
else:
if (escape):
if (byte == KISS.TFEND):
byte = KISS.FEND
if (byte == KISS.TFESC):
byte = KISS.FESC
escape = False
command_buffer = command_buffer+bytes([byte])
if (len(command_buffer) == 2):
bat_percent = command_buffer[1]
if bat_percent > 100:
bat_percent = 100
if bat_percent < 0:
bat_percent = 0
self.r_battery_state = command_buffer[0]
self.r_battery_percent = bat_percent
elif (command == KISS.CMD_RANDOM):
self.r_random = byte
elif (command == KISS.CMD_PLATFORM):
@@ -1153,6 +1251,9 @@ class RNodeInterface(Interface):
elif (byte == KISS.ERROR_TXFAILED):
RNS.log(str(self)+" hardware TX error (code "+RNS.hexrep(byte)+")", RNS.LOG_ERROR)
raise IOError("Hardware transmit failure")
elif (byte == KISS.ERROR_MEMORY_LOW):
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+"): Memory exhausted", RNS.LOG_ERROR)
self.hw_errors.append({"error": KISS.ERROR_MEMORY_LOW, "description": "Memory exhausted on connected device"})
else:
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+")", RNS.LOG_ERROR)
raise IOError("Unknown hardware failure")
@@ -1212,48 +1313,319 @@ class RNodeInterface(Interface):
if self.bt_manager != None:
self.bt_manager.close()
self.reconnect_port()
if not self.detached:
self.reconnect_port()
def reconnect_port(self):
while not self.online and len(self.hw_errors) == 0:
try:
time.sleep(self.reconnect_w)
if self.serial != None and self.port != None:
RNS.log("Attempting to reconnect serial port "+str(self.port)+" for "+str(self)+"...", RNS.LOG_EXTREME)
if self.reconnect_lock.locked():
RNS.log("Dropping superflous reconnect port job")
return
if self.bt_manager != None:
RNS.log("Attempting to reconnect Bluetooth device for "+str(self)+"...", RNS.LOG_EXTREME)
with self.reconnect_lock:
while not self.online and len(self.hw_errors) == 0:
try:
time.sleep(self.reconnect_w)
if self.serial != None and self.port != None:
RNS.log("Attempting to reconnect serial port "+str(self.port)+" for "+str(self)+"...", RNS.LOG_EXTREME)
self.open_port()
if self.bt_manager != None:
RNS.log("Attempting to reconnect Bluetooth device for "+str(self)+"...", RNS.LOG_EXTREME)
if hasattr(self, "serial") and self.serial != None and self.serial.is_open:
self.configure_device()
if self.online:
if self.last_imagedata != None:
self.display_image(self.last_imagedata)
self.enable_external_framebuffer()
elif hasattr(self, "bt_manager") and self.bt_manager != None and self.bt_manager.connected:
self.configure_device()
if self.online:
if self.last_imagedata != None:
self.display_image(self.last_imagedata)
self.enable_external_framebuffer()
self.open_port()
except Exception as e:
RNS.log("Error while reconnecting RNode, the contained exception was: "+str(e), RNS.LOG_ERROR)
if hasattr(self, "serial") and self.serial != None and self.serial.is_open:
self.configure_device()
if self.online:
if self.last_imagedata != None:
self.display_image(self.last_imagedata)
self.enable_external_framebuffer()
elif hasattr(self, "bt_manager") and self.bt_manager != None and self.bt_manager.connected:
self.configure_device()
if self.online:
if self.last_imagedata != None:
self.display_image(self.last_imagedata)
self.enable_external_framebuffer()
if self.online:
RNS.log("Reconnected serial port for "+str(self))
except Exception as e:
RNS.log("Error while reconnecting RNode, the contained exception was: "+str(e), RNS.LOG_ERROR)
if self.online:
RNS.log("Reconnected serial port for "+str(self))
def detach(self):
self.detached = True
self.disable_external_framebuffer()
self.setRadioState(KISS.RADIO_STATE_OFF)
self.leave()
if self.use_ble:
self.ble.close()
def should_ingress_limit(self):
return False
def get_battery_state(self):
return self.r_battery_state
def get_battery_state_string(self):
if self.r_battery_state == RNodeInterface.BATTERY_STATE_CHARGED:
return "charged"
elif self.r_battery_state == RNodeInterface.BATTERY_STATE_CHARGING:
return "charging"
elif self.r_battery_state == RNodeInterface.BATTERY_STATE_DISCHARGING:
return "discharging"
else:
return "unknown"
def get_battery_percent(self):
return self.r_battery_percent
def ble_receive(self, data):
with self.ble_rx_lock:
self.ble_rx_queue += data
def ble_waiting(self):
return len(self.ble_tx_queue) > 0
def get_ble_waiting(self, n):
with self.ble_tx_lock:
data = self.ble_tx_queue[:n]
self.ble_tx_queue = self.ble_tx_queue[n:]
return data
def __str__(self):
return "RNodeInterface["+str(self.name)+"]"
class BLEConnection(BluetoothDispatcher):
UART_SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
UART_RX_CHAR_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
UART_TX_CHAR_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
MAX_GATT_ATTR_LEN = 512
BASE_MTU = 20
TARGET_MTU = 512
MTU_TIMEOUT = 4.0
CONNECT_TIMEOUT = 7.0
RECONNECT_WAIT = 1.0
@property
def is_open(self):
return self.connected
@property
def in_waiting(self):
return len(self.owner.ble_rx_queue) > 0
def write(self, data_bytes):
with self.owner.ble_tx_lock:
self.owner.ble_tx_queue += data_bytes
return len(data_bytes)
def read(self):
with self.owner.ble_rx_lock:
data = self.owner.ble_rx_queue
self.owner.ble_rx_queue = b""
return data
def close(self):
try:
if self.connected:
RNS.log(f"Disconnecting BLE device from {self.owner}", RNS.LOG_DEBUG)
# RNS.log("Waiting for BLE write buffer to empty...")
timeout = time.time() + 10
while self.owner.ble_waiting() and self.write_thread != None and time.time() < timeout:
time.sleep(0.1)
# if time.time() > timeout:
# RNS.log("Writing timed out")
# else:
# RNS.log("Writing concluded")
self.rx_char = None
self.tx_char = None
self.mtu = BLEConnection.BASE_MTU
self.mtu_requested_time = None
if self.write_thread != None:
# RNS.log("Waiting for write thread to finish...")
while self.write_thread != None:
time.sleep(0.1)
# RNS.log("Writing finished, closing GATT connection")
self.close_gatt()
with self.owner.ble_rx_lock:
self.owner.ble_rx_queue = b""
with self.owner.ble_tx_lock:
self.owner.ble_tx_queue = b""
self.connected = False
self.ble_device = None
except Exception as e:
RNS.log("An error occurred while closing BLE connection for {self.owner}: {e}", RNS.LOG_ERROR)
RNS.trace_exception(e)
def __init__(self, owner=None, target_name=None, target_bt_addr=None):
super(BLEConnection, self).__init__()
self.owner = owner
self.target_name = target_name
self.target_bt_addr = target_bt_addr
self.connect_timeout = BLEConnection.CONNECT_TIMEOUT
self.ble_device = None
self.rx_char = None
self.tx_char = None
self.connected = False
self.was_connected = False
self.connected_time = None
self.mtu_requested_time = None
self.running = False
self.should_run = False
self.connect_job_running = False
self.write_thread = None
self.mtu = BLEConnection.BASE_MTU
self.target_mtu = BLEConnection.TARGET_MTU
self.bt_manager = AndroidBluetoothManager(owner=self)
self.should_run = True
self.connection_thread = threading.Thread(target=self.connection_job, daemon=True).start()
def write_loop(self):
try:
while self.connected and self.rx_char != None:
if self.owner.ble_waiting():
data = self.owner.get_ble_waiting(self.mtu)
self.write_characteristic(self.rx_char, data)
else:
time.sleep(0.1)
except Exception as e:
RNS.log("An error occurred in {self} write loop: {e}", RNS.LOG_ERROR)
RNS.trace_exception(e)
self.write_thread = None
def connection_job(self):
while self.should_run:
if self.bt_manager.bt_enabled():
if self.ble_device == None:
self.ble_device = self.find_target_device()
if self.ble_device != None:
if not self.connected:
if self.was_connected:
RNS.log(f"Throttling BLE reconnect for {BLEConnection.RECONNECT_WAIT} seconds", RNS.LOG_DEBUG)
time.sleep(BLEConnection.RECONNECT_WAIT)
self.connect_device()
else:
if self.connected:
RNS.log("Bluetooth was disabled, closing active BLE device connection", RNS.LOG_ERROR)
self.close()
time.sleep(2)
def connect_device(self):
if self.ble_device != None and self.bt_manager.bt_enabled():
RNS.log(f"Trying to connect BLE device {self.ble_device.getName()} / {self.ble_device.getAddress()} for {self.owner}...", RNS.LOG_DEBUG)
self.mtu = BLEConnection.BASE_MTU
self.connect_by_device_address(self.ble_device.getAddress())
end = time.time() + BLEConnection.CONNECT_TIMEOUT
while time.time() < end and not self.connected:
time.sleep(0.25)
if self.connected:
self.owner.port = f"ble://{self.ble_device.getAddress()}"
self.write_thread = threading.Thread(target=self.write_loop, daemon=True)
self.write_thread.start()
else:
RNS.log(f"BLE device connection timed out for {self.owner}", RNS.LOG_DEBUG)
if self.mtu_requested_time:
RNS.log("MTU update timeout, tearing down connection")
self.owner.hw_errors.append({"error": KISS.ERROR_INVALID_BLE_MTU, "description": "The Bluetooth Low Energy transfer MTU could not be configured for the connected device, and communication has failed. Restart Reticulum and any connected applications to retry connecting."})
self.close()
self.should_run = False
self.close_gatt()
self.connect_job_running = False
def device_disconnected(self):
RNS.log(f"BLE device for {self.owner} disconnected", RNS.LOG_NOTICE)
self.connected = False
self.ble_device = None
self.close_gatt()
def find_target_device(self):
found_device = None
potential_devices = self.bt_manager.get_paired_devices()
if self.target_bt_addr != None:
for device in potential_devices:
if (device.getType() == AndroidBluetoothManager.DEVICE_TYPE_LE) or (device.getType() == AndroidBluetoothManager.DEVICE_TYPE_DUAL):
if str(device.getAddress()).replace(":", "").lower() == str(self.target_bt_addr).replace(":", "").lower():
found_device = device
break
if not found_device and self.target_name != None:
for device in potential_devices:
if (device.getType() == AndroidBluetoothManager.DEVICE_TYPE_LE) or (device.getType() == AndroidBluetoothManager.DEVICE_TYPE_DUAL):
if device.getName().lower() == self.target_name.lower():
found_device = device
break
if not found_device:
for device in potential_devices:
if (device.getType() == AndroidBluetoothManager.DEVICE_TYPE_LE) or (device.getType() == AndroidBluetoothManager.DEVICE_TYPE_DUAL):
if device.getName().startswith("RNode "):
found_device = device
break
return found_device
def on_connection_state_change(self, status, state):
if status == GATT_SUCCESS and state:
self.discover_services()
else:
self.device_disconnected()
def on_services(self, status, services):
if status == GATT_SUCCESS:
self.rx_char = services.search(BLEConnection.UART_RX_CHAR_UUID)
if self.rx_char is not None:
self.tx_char = services.search(BLEConnection.UART_TX_CHAR_UUID)
if self.tx_char is not None:
if self.enable_notifications(self.tx_char):
RNS.log("Enabled notifications for BLE TX characteristic", RNS.LOG_DEBUG)
RNS.log(f"Requesting BLE connection MTU update to {self.target_mtu}", RNS.LOG_DEBUG)
self.mtu_requested_time = time.time()
self.request_mtu(self.target_mtu)
else:
RNS.log("Could not enable notifications for BLE TX characteristic", RNS.LOG_ERROR)
else:
RNS.log("BLE device service discovery failure", RNS.LOG_ERROR)
def on_mtu_changed(self, mtu, status):
if status == GATT_SUCCESS:
self.mtu = min(mtu-5, BLEConnection.MAX_GATT_ATTR_LEN)
RNS.log(f"BLE MTU updated to {self.mtu} for {self.owner}", RNS.LOG_DEBUG)
self.connected = True
self.was_connected = True
self.connected_time = time.time()
self.mtu_requested_time = None
else:
RNS.log(f"MTU update request did not succeed, mtu={mtu}, status={status}", RNS.LOG_ERROR)
def on_characteristic_changed(self, characteristic):
if characteristic.getUuid().toString() == BLEConnection.UART_TX_CHAR_UUID:
recvd = bytes(characteristic.getValue())
self.owner.ble_receive(recvd)
+278 -20
View File
@@ -54,6 +54,7 @@ class KISS():
CMD_STAT_SNR = 0x24
CMD_STAT_CHTM = 0x25
CMD_STAT_PHYPRM = 0x26
CMD_STAT_BAT = 0x27
CMD_BLINK = 0x30
CMD_RANDOM = 0x40
CMD_FB_EXT = 0x41
@@ -77,9 +78,12 @@ class KISS():
ERROR_INITRADIO = 0x01
ERROR_TXFAILED = 0x02
ERROR_EEPROM_LOCKED = 0x03
ERROR_QUEUE_FULL = 0x04
ERROR_MEMORY_LOW = 0x05
PLATFORM_AVR = 0x90
PLATFORM_ESP32 = 0x80
PLATFORM_NRF52 = 0x70
@staticmethod
def escape(data):
@@ -107,7 +111,12 @@ class RNodeInterface(Interface):
Q_SNR_MAX = 6
Q_SNR_STEP = 2
def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False, id_interval = None, id_callsign = None, st_alock = None, lt_alock = None):
BATTERY_STATE_UNKNOWN = 0x00
BATTERY_STATE_DISCHARGING = 0x01
BATTERY_STATE_CHARGING = 0x02
BATTERY_STATE_CHARGED = 0x03
def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False, id_interval = None, id_callsign = None, st_alock = None, lt_alock = None, ble_addr = None, ble_name = None, force_ble=False):
if RNS.vendor.platformutils.is_android():
raise SystemError("Invalid interface type. The Android-specific RNode interface must be used on Android")
@@ -136,6 +145,15 @@ class RNodeInterface(Interface):
self.detached = False
self.reconnecting= False
self.use_ble = False
self.ble_name = ble_name
self.ble_addr = ble_addr
self.ble = None
self.ble_rx_lock = threading.Lock()
self.ble_tx_lock = threading.Lock()
self.ble_rx_queue= b""
self.ble_tx_queue= b""
self.frequency = frequency
self.bandwidth = bandwidth
self.txpower = txpower
@@ -179,12 +197,17 @@ class RNodeInterface(Interface):
self.r_symbol_rate = None
self.r_preamble_symbols = None
self.r_premable_time_ms = None
self.r_battery_state = RNodeInterface.BATTERY_STATE_UNKNOWN
self.r_battery_percent = 0
self.packet_queue = []
self.flow_control = flow_control
self.interface_ready = False
self.announce_rate_target = None
if force_ble or self.ble_addr != None or self.ble_name != None:
self.use_ble = True
self.validcfg = True
if (self.frequency < RNodeInterface.FREQ_MIN or self.frequency > RNodeInterface.FREQ_MAX):
RNS.log("Invalid frequency configured for "+str(self), RNS.LOG_ERROR)
@@ -248,20 +271,31 @@ class RNodeInterface(Interface):
def open_port(self):
RNS.log("Opening serial port "+self.port+"...")
self.serial = self.pyserial.Serial(
port = self.port,
baudrate = self.speed,
bytesize = self.databits,
parity = self.pyserial.PARITY_NONE,
stopbits = self.stopbits,
xonxoff = False,
rtscts = False,
timeout = 0,
inter_byte_timeout = None,
write_timeout = None,
dsrdtr = False,
)
if not self.use_ble:
RNS.log("Opening serial port "+self.port+"...")
self.serial = self.pyserial.Serial(
port = self.port,
baudrate = self.speed,
bytesize = self.databits,
parity = self.pyserial.PARITY_NONE,
stopbits = self.stopbits,
xonxoff = False,
rtscts = False,
timeout = 0,
inter_byte_timeout = None,
write_timeout = None,
dsrdtr = False,
)
else:
RNS.log(f"Opening BLE connection for {self}...")
if self.ble == None:
self.ble = BLEConnection(owner=self, target_name=self.ble_name, target_bt_addr=self.ble_addr)
self.serial = self.ble
open_time = time.time()
while not self.ble.connected and time.time() < open_time + self.ble.CONNECT_TIMEOUT:
time.sleep(1)
def configure_device(self):
@@ -279,13 +313,23 @@ class RNodeInterface(Interface):
thread.start()
self.detect()
sleep(0.2)
if not self.use_ble:
sleep(0.2)
else:
ble_detect_timeout = 5
detect_time = time.time()
while not self.detected and time.time() < detect_time + ble_detect_timeout:
time.sleep(0.1)
if self.detected:
detect_time = RNS.prettytime(time.time()-detect_time)
else:
RNS.log(f"RNode detect timed out over {self.port}", RNS.LOG_ERROR)
if not self.detected:
RNS.log("Could not detect device for "+str(self), RNS.LOG_ERROR)
self.serial.close()
else:
if self.platform == KISS.PLATFORM_ESP32:
if self.platform == KISS.PLATFORM_ESP32 or self.platform == KISS.PLATFORM_NRF52:
self.display = True
RNS.log("Serial port "+self.port+" is now open")
@@ -313,6 +357,9 @@ class RNodeInterface(Interface):
self.setLTALock()
self.setRadioState(KISS.RADIO_STATE_ON)
if self.use_ble:
time.sleep(2)
def detect(self):
kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND])
written = self.serial.write(kiss_command)
@@ -447,9 +494,12 @@ class RNodeInterface(Interface):
raise IOError("An IO error occurred while configuring radio state for "+str(self))
def validate_firmware(self):
if (self.maj_version >= RNodeInterface.REQUIRED_FW_VER_MAJ):
if (self.min_version >= RNodeInterface.REQUIRED_FW_VER_MIN):
self.firmware_ok = True
if (self.maj_version > RNodeInterface.REQUIRED_FW_VER_MAJ):
self.firmware_ok = True
else:
if (self.maj_version >= RNodeInterface.REQUIRED_FW_VER_MAJ):
if (self.min_version >= RNodeInterface.REQUIRED_FW_VER_MIN):
self.firmware_ok = True
if self.firmware_ok:
return
@@ -765,6 +815,25 @@ class RNodeInterface(Interface):
RNS.log(str(self)+" Radio reporting symbol time is "+str(round(self.r_symbol_time_ms,2))+"ms (at "+str(self.r_symbol_rate)+" baud)", RNS.LOG_DEBUG)
RNS.log(str(self)+" Radio reporting preamble is "+str(self.r_preamble_symbols)+" symbols ("+str(self.r_premable_time_ms)+"ms)", RNS.LOG_DEBUG)
RNS.log(str(self)+" Radio reporting CSMA slot time is "+str(self.r_csma_slot_time_ms)+"ms", RNS.LOG_DEBUG)
elif (command == KISS.CMD_STAT_BAT):
if (byte == KISS.FESC):
escape = True
else:
if (escape):
if (byte == KISS.TFEND):
byte = KISS.FEND
if (byte == KISS.TFESC):
byte = KISS.FESC
escape = False
command_buffer = command_buffer+bytes([byte])
if (len(command_buffer) == 2):
bat_percent = command_buffer[1]
if bat_percent > 100:
bat_percent = 100
if bat_percent < 0:
bat_percent = 0
self.r_battery_state = command_buffer[0]
self.r_battery_percent = bat_percent
elif (command == KISS.CMD_RANDOM):
self.r_random = byte
elif (command == KISS.CMD_PLATFORM):
@@ -778,6 +847,9 @@ class RNodeInterface(Interface):
elif (byte == KISS.ERROR_TXFAILED):
RNS.log(str(self)+" hardware TX error (code "+RNS.hexrep(byte)+")", RNS.LOG_ERROR)
raise IOError("Hardware transmit failure")
elif (byte == KISS.ERROR_MEMORY_LOW):
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+"): Memory exhausted", RNS.LOG_ERROR)
self.hw_errors.append({"error": KISS.ERROR_MEMORY_LOW, "description": "Memory exhausted on connected device"})
else:
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+")", RNS.LOG_ERROR)
raise IOError("Unknown hardware failure")
@@ -852,9 +924,195 @@ class RNodeInterface(Interface):
self.disable_external_framebuffer()
self.setRadioState(KISS.RADIO_STATE_OFF)
self.leave()
if self.use_ble:
self.ble.close()
def should_ingress_limit(self):
return False
def get_battery_state(self):
return self.r_battery_state
def get_battery_state_string(self):
if self.r_battery_state == RNodeInterface.BATTERY_STATE_CHARGED:
return "charged"
elif self.r_battery_state == RNodeInterface.BATTERY_STATE_CHARGING:
return "charging"
elif self.r_battery_state == RNodeInterface.BATTERY_STATE_DISCHARGING:
return "discharging"
else:
return "unknown"
def get_battery_percent(self):
return self.r_battery_percent
def ble_receive(self, data):
with self.ble_rx_lock:
self.ble_rx_queue += data
def ble_waiting(self):
return len(self.ble_tx_queue) > 0
def get_ble_waiting(self, n):
with self.ble_tx_lock:
data = self.ble_tx_queue[:n]
self.ble_tx_queue = self.ble_tx_queue[n:]
return data
def __str__(self):
return "RNodeInterface["+str(self.name)+"]"
class BLEConnection():
UART_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
UART_RX_CHAR_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
UART_TX_CHAR_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
bleak = None
SCAN_TIMEOUT = 2.0
CONNECT_TIMEOUT = 5.0
@property
def is_open(self):
return self.connected
@property
def in_waiting(self):
buflen = len(self.owner.ble_rx_queue)
return buflen > 0
def write(self, data_bytes):
with self.owner.ble_tx_lock:
self.owner.ble_tx_queue += data_bytes
return len(data_bytes)
def read(self, n):
with self.owner.ble_rx_lock:
data = self.owner.ble_rx_queue[:n]
self.owner.ble_rx_queue = self.owner.ble_rx_queue[n:]
return data
def close(self):
if self.connected and self.ble_device:
RNS.log(f"Disconnecting BLE device from {self.owner}", RNS.LOG_DEBUG)
self.must_disconnect = True
while self.connect_job_running:
time.sleep(0.1)
def __init__(self, owner=None, target_name=None, target_bt_addr=None):
self.owner = owner
self.target_name = target_name
self.target_bt_addr = target_bt_addr
self.scan_timeout = BLEConnection.SCAN_TIMEOUT
self.ble_device = None
self.connected = False
self.running = False
self.should_run = False
self.must_disconnect = False
self.connect_job_running = False
import importlib
if BLEConnection.bleak == None:
if importlib.util.find_spec("bleak") != None:
import bleak
BLEConnection.bleak = bleak
import asyncio
BLEConnection.asyncio = asyncio
else:
RNS.log("Using the RNode interface over BLE requires a the \"bleak\" module to be installed.", RNS.LOG_CRITICAL)
RNS.log("You can install one with the command: python3 -m pip install bleak", RNS.LOG_CRITICAL)
RNS.panic()
self.should_run = True
self.connection_thread = threading.Thread(target=self.connection_job, daemon=True).start()
def connection_job(self):
while (self.should_run):
if self.ble_device == None:
self.ble_device = self.find_target_device()
if type(self.ble_device) == self.bleak.backends.device.BLEDevice:
if not self.connected:
self.connect_device()
time.sleep(1)
def connect_device(self):
if self.ble_device != None and type(self.ble_device) == self.bleak.backends.device.BLEDevice:
RNS.log(f"Connecting BLE device {self.ble_device} for {self.owner}...", RNS.LOG_DEBUG)
async def connect_job():
self.connect_job_running = True
async with self.bleak.BleakClient(self.ble_device, disconnected_callback=self.device_disconnected) as ble_client:
def handle_rx(device, data):
if self.owner != None:
self.owner.ble_receive(data)
self.connected = True
self.ble_device = ble_client
self.owner.port = str(f"ble://{ble_client.address}")
loop = self.asyncio.get_running_loop()
uart_service = ble_client.services.get_service(BLEConnection.UART_SERVICE_UUID)
rx_characteristic = uart_service.get_characteristic(BLEConnection.UART_RX_CHAR_UUID)
await ble_client.start_notify(BLEConnection.UART_TX_CHAR_UUID, handle_rx)
while self.connected:
if self.owner != None and self.owner.ble_waiting():
outbound_data = self.owner.get_ble_waiting(rx_characteristic.max_write_without_response_size)
await ble_client.write_gatt_char(rx_characteristic, outbound_data, response=False)
elif self.must_disconnect:
await ble_client.disconnect()
else:
await self.asyncio.sleep(0.1)
try:
self.asyncio.run(connect_job())
except Exception as e:
RNS.log(f"Could not connect BLE device {self.ble_device} for {self.owner}. Possibly missing authentication.", RNS.LOG_ERROR)
self.connect_job_running = False
def device_disconnected(self, device):
RNS.log(f"BLE device for {self.owner} disconnected", RNS.LOG_NOTICE)
self.connected = False
self.ble_device = None
def find_target_device(self):
RNS.log(f"Searching for attachable BLE device for {self.owner}...", RNS.LOG_EXTREME)
def device_filter(device: self.bleak.backends.device.BLEDevice, adv: self.bleak.backends.scanner.AdvertisementData):
if BLEConnection.UART_SERVICE_UUID.lower() in adv.service_uuids:
if self.device_bonded(device):
if self.target_bt_addr == None and self.target_name == None:
if device.name.startswith("RNode "):
return True
if self.target_bt_addr == None or (device.address != None and device.address == self.target_bt_addr):
if self.target_name == None or (device.name != None and device.name == self.target_name):
return True
else:
if self.target_bt_addr != None and device.address == self.target_bt_addr:
RNS.log(f"Can't connect to target device {self.target_bt_addr} over BLE, device is not bonded", RNS.LOG_ERROR)
elif self.target_name != None and device.name == self.target_name:
RNS.log(f"Can't connect to target device {self.target_name} over BLE, device is not bonded", RNS.LOG_ERROR)
return False
device = self.asyncio.run(self.bleak.BleakScanner.find_device_by_filter(device_filter, timeout=self.scan_timeout))
return device
def device_bonded(self, device):
try:
if hasattr(device, "details"):
if "props" in device.details and "Bonded" in device.details["props"]:
if device.details["props"]["Bonded"] == True:
return True
except Exception as e:
RNS.log(f"Error while determining device bond status for {device}, the contained exception was: {e}", RNS.LOG_ERROR)
return False
+14 -7
View File
@@ -70,7 +70,7 @@ class KISS():
CMD_INT1_DATA = 0x10
CMD_INT2_DATA = 0x20
CMD_INT3_DATA = 0x70
CMD_INT4_DATA = 0x80
CMD_INT4_DATA = 0x75
CMD_INT5_DATA = 0x90
CMD_INT6_DATA = 0xA0
CMD_INT7_DATA = 0xB0
@@ -82,8 +82,8 @@ class KISS():
CMD_SEL_INT0 = 0x1E
CMD_SEL_INT1 = 0x1F
CMD_SEL_INT2 = 0x2F
CMD_SEL_INT3 = 0x7F
CMD_SEL_INT4 = 0x8F
CMD_SEL_INT3 = 0x74
CMD_SEL_INT4 = 0x7F
CMD_SEL_INT5 = 0x9F
CMD_SEL_INT6 = 0xAF
CMD_SEL_INT7 = 0xBF
@@ -106,6 +106,7 @@ class KISS():
PLATFORM_AVR = 0x90
PLATFORM_ESP32 = 0x80
PLATFORM_NRF52 = 0x70
SX127X = 0x00
SX1276 = 0x01
@@ -166,7 +167,7 @@ class RNodeMultiInterface(Interface):
CALLSIGN_MAX_LEN = 32
REQUIRED_FW_VER_MAJ = 1
REQUIRED_FW_VER_MIN = 73
REQUIRED_FW_VER_MIN = 74
RECONNECT_WAIT = 5
@@ -249,6 +250,7 @@ class RNodeMultiInterface(Interface):
if (not self.validcfg):
raise ValueError("The configuration for "+str(self)+" contains errors, interface is offline")
def start(self):
try:
self.open_port()
@@ -297,7 +299,7 @@ class RNodeMultiInterface(Interface):
RNS.log("Could not detect device for "+str(self), RNS.LOG_ERROR)
self.serial.close()
else:
if self.platform == KISS.PLATFORM_ESP32:
if self.platform == KISS.PLATFORM_ESP32 or self.platform == KISS.PLATFORM_NRF52:
self.display = True
RNS.log("Serial port "+self.port+" is now open")
@@ -323,8 +325,8 @@ class RNodeMultiInterface(Interface):
lt_alock=subint[9]
)
interface.OUT = self.OUT
interface.IN = self.IN
interface.OUT = subint[10]
interface.IN = True
interface.announce_rate_target = self.announce_rate_target
interface.mode = self.mode
@@ -1006,6 +1008,11 @@ class RNodeSubInterface(Interface):
self.parent_interface = parent_interface
self.announce_rate_target = None
self.mode = None
self.announce_cap = None
self.bitrate = None
self.ifac_size = None
# add this interface to the subinterfaces array
self.parent_interface.subinterfaces[index] = self
+1 -1
View File
@@ -453,7 +453,7 @@ class PacketReceipt:
# This is an explicit proof
proof_hash = proof[:RNS.Identity.HASHLENGTH//8]
signature = proof[RNS.Identity.HASHLENGTH//8:RNS.Identity.HASHLENGTH//8+RNS.Identity.SIGLENGTH//8]
if proof_hash == self.hash:
if proof_hash == self.hash and hasattr(self.destination, "identity") and self.destination.identity != None:
proof_valid = self.destination.identity.validate(signature, self.hash)
if proof_valid:
self.status = PacketReceipt.DELIVERED
+20
View File
@@ -54,6 +54,9 @@ class Resource:
# The maximum window size for transfers on slow links
WINDOW_MAX_SLOW = 10
# The maximum window size for transfers on very slow links
WINDOW_MAX_VERY_SLOW = 4
# The maximum window size for transfers on fast links
WINDOW_MAX_FAST = 75
@@ -65,12 +68,22 @@ class Resource:
# rounds, the fast link window size will be allowed.
FAST_RATE_THRESHOLD = WINDOW_MAX_SLOW - WINDOW - 2
# If the very slow rate is sustained for this many request
# rounds, window will be capped to the very slow limit.
VERY_SLOW_RATE_THRESHOLD = 2
# If the RTT rate is higher than this value,
# the max window size for fast links will be used.
# The default is 50 Kbps (the value is stored in
# bytes per second, hence the "/ 8").
RATE_FAST = (50*1000) / 8
# If the RTT rate is lower than this value,
# the window size will be capped at .
# The default is 50 Kbps (the value is stored in
# bytes per second, hence the "/ 8").
RATE_VERY_SLOW = (2*1000) / 8
# The minimum allowed flexibility of the window size.
# The difference between window_max and window_min
# will never be smaller than this value.
@@ -275,6 +288,7 @@ class Resource:
self.req_resp_rtt_rate = 0
self.rtt_rxd_bytes_at_part_req = 0
self.fast_rate_rounds = 0
self.very_slow_rate_rounds = 0
self.request_id = request_id
self.is_response = is_response
@@ -759,6 +773,12 @@ class Resource:
if self.fast_rate_rounds == Resource.FAST_RATE_THRESHOLD:
self.window_max = Resource.WINDOW_MAX_FAST
if self.fast_rate_rounds == 0 and self.req_data_rtt_rate < Resource.RATE_VERY_SLOW and self.very_slow_rate_rounds < Resource.VERY_SLOW_RATE_THRESHOLD:
self.very_slow_rate_rounds += 1
if self.very_slow_rate_rounds == Resource.VERY_SLOW_RATE_THRESHOLD:
self.window_max = Resource.WINDOW_MAX_VERY_SLOW
self.request_next()
else:
self.receiving_part = False
+47 -7
View File
@@ -916,11 +916,28 @@ class Reticulum:
st_alock = float(c["airtime_limit_short"]) if "airtime_limit_short" in c else None
lt_alock = float(c["airtime_limit_long"]) if "airtime_limit_long" in c else None
force_ble = False
ble_name = None
ble_addr = None
port = c["port"] if "port" in c else None
if port == None:
raise ValueError("No port specified for RNode interface")
if port != None:
ble_uri_scheme = "ble://"
if port.lower().startswith(ble_uri_scheme):
force_ble = True
ble_string = port[len(ble_uri_scheme):]
port = None
if len(ble_string) == 0:
pass
elif len(ble_string.split(":")) == 6 and len(ble_string) == 17:
ble_addr = ble_string
else:
ble_name = ble_string
interface = RNodeInterface.RNodeInterface(
RNS.Transport,
name,
@@ -934,7 +951,10 @@ class Reticulum:
id_interval = id_interval,
id_callsign = id_callsign,
st_alock = st_alock,
lt_alock = lt_alock
lt_alock = lt_alock,
ble_addr = ble_addr,
ble_name = ble_name,
force_ble = force_ble,
)
if "outgoing" in c and c.as_bool("outgoing") == False:
@@ -971,7 +991,7 @@ class Reticulum:
enabled_count += 1
# Create an array with a row for each subinterface
subint_config = [[0 for x in range(10)] for y in range(enabled_count)]
subint_config = [[0 for x in range(11)] for y in range(enabled_count)]
subint_index = 0
for subinterface in c:
@@ -1000,6 +1020,11 @@ class Reticulum:
subint_config[subint_index][8] = st_alock
lt_alock = float(subinterface_config["airtime_limit_long"]) if "airtime_limit_long" in subinterface_config else None
subint_config[subint_index][9] = lt_alock
if "outgoing" in subinterface_config and subinterface_config.as_bool("outgoing") == False:
subint_config[subint_index][10] = False
else:
subint_config[subint_index][10] = True
subint_index += 1
# if no subinterfaces are defined
@@ -1025,10 +1050,8 @@ class Reticulum:
id_callsign = id_callsign
)
if "outgoing" in c and c.as_bool("outgoing") == False:
interface.OUT = False
else:
interface.OUT = True
interface.IN = False
interface.OUT = False
interface.mode = interface_mode
@@ -1079,6 +1102,9 @@ class Reticulum:
RNS.Transport.interfaces.append(interface)
if isinstance(interface, RNS.Interfaces.RNodeMultiInterface.RNodeMultiInterface):
interface.start()
else:
RNS.log("Skipping disabled interface \""+name+"\"", RNS.LOG_DEBUG)
@@ -1258,6 +1284,10 @@ class Reticulum:
else:
ifstats["clients"] = None
if hasattr(interface, "parent_interface") and interface.parent_interface != None:
ifstats["parent_interface_name"] = str(interface.parent_interface)
ifstats["parent_interface_hash"] = interface.parent_interface.get_hash()
if hasattr(interface, "i2p") and hasattr(interface, "connectable"):
if interface.connectable:
ifstats["i2p_connectable"] = True
@@ -1295,6 +1325,13 @@ class Reticulum:
if hasattr(interface, "r_channel_load_long"):
ifstats["channel_load_long"] = interface.r_channel_load_long
if hasattr(interface, "r_battery_state"):
if interface.r_battery_state != 0x00:
ifstats["battery_state"] = interface.r_battery_state
if hasattr(interface, "r_battery_percent"):
ifstats["battery_percent"] = interface.r_battery_percent
if hasattr(interface, "bitrate"):
if interface.bitrate != None:
ifstats["bitrate"] = interface.bitrate
@@ -1323,6 +1360,9 @@ class Reticulum:
ifstats["announce_queue"] = None
ifstats["name"] = str(interface)
ifstats["short_name"] = str(interface.name)
ifstats["hash"] = interface.get_hash()
ifstats["type"] = str(type(interface).__name__)
ifstats["rxb"] = interface.rxb
ifstats["txb"] = interface.txb
ifstats["incoming_announce_frequency"] = interface.incoming_announce_frequency()
+1 -1
View File
@@ -65,7 +65,7 @@ class Transport:
PATH_REQUEST_TIMEOUT = 15 # Default timuout for client path requests in seconds
PATH_REQUEST_GRACE = 0.4 # Grace time before a path announcement is made, allows directly reachable peers to respond first
PATH_REQUEST_RG = 0.6 # Extra grace time for roaming-mode interfaces to allow more suitable peers to respond first
PATH_REQUEST_RG = 1.5 # Extra grace time for roaming-mode interfaces to allow more suitable peers to respond first
PATH_REQUEST_MI = 20 # Minimum interval in seconds for automated path requests
STATE_UNKNOWN = 0x00
+209 -14
View File
@@ -41,7 +41,7 @@ import RNS
RNS.logtimefmt = "%H:%M:%S"
RNS.compact_log_fmt = True
program_version = "2.1.3"
program_version = "2.2.0"
eth_addr = "0xFDabC71AC4c0C78C95aDDDe3B4FA19d6273c5E73"
btc_addr = "35G9uWVzrpJJibzUwpNUQGQNFzLirhrYAH"
xmr_addr = "87HcDx6jRSkMQ9nPRd5K9hGGpZLn2s7vWETjMaVM5KfV4TD36NcYa8J8WSxhTSvBzzFpqDwp2fg5GX2moZ7VAP9QMZCZGET"
@@ -81,7 +81,9 @@ class KISS():
CMD_BLINK = 0x30
CMD_RANDOM = 0x40
CMD_DISP_INT = 0x45
CMD_NP_INT = 0x65
CMD_DISP_ADR = 0x63
CMD_DISP_BLNK = 0x64
CMD_BT_CTRL = 0x46
CMD_BT_PIN = 0x62
CMD_BOARD = 0x47
@@ -137,6 +139,8 @@ class ROM():
MODEL_A8 = 0xA8
MODEL_A2 = 0xA2
MODEL_A7 = 0xA7
MODEL_A5 = 0xA5
MODEL_AA = 0xAA
PRODUCT_T32_10 = 0xB2
MODEL_BA = 0xBA
@@ -167,6 +171,14 @@ class ROM():
MODEL_E3 = 0xE3
MODEL_E8 = 0xE8
PRODUCT_TBEAM_S_V1= 0xEA
MODEL_DB = 0xDB
MODEL_DC = 0xDC
PRODUCT_TDECK = 0xD0
MODEL_D4 = 0xD4
MODEL_D9 = 0xD9
PRODUCT_RAK4631 = 0x10
MODEL_11 = 0x11
MODEL_12 = 0x12
@@ -205,6 +217,7 @@ class ROM():
BOARD_RNODE = 0x31
BOARD_HMBRW = 0x32
BOARD_TBEAM = 0x33
BOARD_TDECK = 0x3B
BOARD_HUZZAH32 = 0x34
BOARD_GENERIC_ESP32 = 0x35
BOARD_LORA32_V2_0 = 0x36
@@ -212,13 +225,15 @@ class ROM():
BOARD_TECHO = 0x43
BOARD_RAK4631 = 0x51
MANUAL_FLASH_MODELS = [MODEL_A1, MODEL_A6]
MANUAL_FLASH_MODELS = []
mapped_product = ROM.PRODUCT_RNODE
products = {
ROM.PRODUCT_RNODE: "RNode",
ROM.PRODUCT_HMBRW: "Hombrew RNode",
ROM.PRODUCT_TBEAM: "LilyGO T-Beam",
ROM.PRODUCT_TBEAM_S_V1:"LilyGO T-Beam Supreme",
ROM.PRODUCT_TDECK: "LilyGO T-Deck",
ROM.PRODUCT_T32_10: "LilyGO LoRa32 v1.0",
ROM.PRODUCT_T32_20: "LilyGO LoRa32 v2.0",
ROM.PRODUCT_T32_21: "LilyGO LoRa32 v2.1",
@@ -247,6 +262,8 @@ models = {
0xA9: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware.hex", "SX1276"],
0xA1: [410000000, 525000000, 22, "410 - 525 MHz", "rnode_firmware_t3s3.zip", "SX1268"],
0xA6: [820000000, 1020000000, 22, "820 - 960 MHz", "rnode_firmware_t3s3.zip", "SX1262"],
0xA5: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_t3s3_sx127x.zip", "SX1278"],
0xAA: [820000000, 1020000000, 17, "820 - 960 MHz", "rnode_firmware_t3s3_sx127x.zip", "SX1276"],
0xA2: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng21.zip", "SX1278"],
0xA7: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng21.zip", "SX1276"],
0xA3: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng20.zip", "SX1278"],
@@ -265,12 +282,16 @@ models = {
0xCA: [863000000, 928000000, 21, "863 - 928 MHz", "rnode_firmware_heltec32v3.zip", "SX1262"],
0xE4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_tbeam.zip", "SX1278"],
0xE9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_tbeam.zip", "SX1276"],
0xD4: [420000000, 520000000, 22, "420 - 520 MHz", "rnode_firmware_tdeck.zip", "SX1268"],
0xD9: [850000000, 950000000, 22, "850 - 950 MHz", "rnode_firmware_tdeck.zip", "SX1262"],
0xDB: [420000000, 520000000, 22, "420 - 520 MHz", "rnode_firmware_tbeam_supreme.zip", "SX1268"],
0xDC: [850000000, 950000000, 22, "850 - 950 MHz", "rnode_firmware_tbeam_supreme.zip", "SX1262"],
0xE3: [420000000, 520000000, 22, "420 - 520 MHz", "rnode_firmware_tbeam_sx1262.zip", "SX1268"],
0xE8: [850000000, 950000000, 22, "850 - 950 MHz", "rnode_firmware_tbeam_sx1262.zip", "SX1262"],
0x11: [430000000, 510000000, 22, "430 - 510 MHz", "rnode_firmware_rak4631.zip", "SX1262"],
0x12: [779000000, 928000000, 22, "779 - 928 MHz", "rnode_firmware_rak4631.zip", "SX1262"],
0x11: [430000000, 510000000, 22, "430 - 510 MHz", "rnode_firmware_rak4631_sx1280.zip", "SX1262 + SX1280"],
0x12: [779000000, 928000000, 22, "779 - 928 MHz", "rnode_firmware_rak4631_sx1280.zip", "SX1262 + SX1280"],
0x13: [430000000, 510000000, 22, "430 - 510 MHz", "rnode_firmware_rak4631_sx1280.zip", "SX1262 + SX1280"],
0x14: [779000000, 928000000, 22, "779 - 928 MHz", "rnode_firmware_rak4631_sx1280.zip", "SX1262 + SX1280"],
0x16: [779000000, 928000000, 22, "430 - 510 Mhz", "rnode_firmware_techo.zip", "SX1262"],
0x17: [779000000, 928000000, 22, "779 - 928 Mhz", "rnode_firmware_techo.zip", "SX1262"],
0x21: [820000000, 960000000, 22, "820 - 960 MHz", "rnode_firmware_opencom_xl.zip", "SX1262 + SX1280"],
@@ -637,6 +658,20 @@ class RNode():
if written != len(kiss_command):
raise IOError("An IO error occurred while sending display intensity command to device")
def set_display_blanking(self, blanking_timeout):
data = bytes([blanking_timeout & 0xFF])
kiss_command = bytes([KISS.FEND])+bytes([KISS.CMD_DISP_BLNK])+data+bytes([KISS.FEND])
written = self.serial.write(kiss_command)
if written != len(kiss_command):
raise IOError("An IO error occurred while sending display blanking timeout command to device")
def set_neopixel_intensity(self, intensity):
data = bytes([intensity & 0xFF])
kiss_command = bytes([KISS.FEND])+bytes([KISS.CMD_NP_INT])+data+bytes([KISS.FEND])
written = self.serial.write(kiss_command)
if written != len(kiss_command):
raise IOError("An IO error occurred while sending NeoPixel intensity command to device")
def set_display_address(self, address):
data = bytes([address & 0xFF])
kiss_command = bytes([KISS.FEND])+bytes([KISS.CMD_DISP_ADR])+data+bytes([KISS.FEND])
@@ -1159,6 +1194,7 @@ def ensure_firmware_file(fw_filename):
pass
else:
RNS.log("")
RNS.log(f"Firmware hash {file_hash} but should be {selected_hash}, possibly due to download corruption.")
RNS.log("Firmware corrupt. Try clearing the local firmware cache with: rnodeconf --clear-cache")
graceful_exit(96)
@@ -1261,8 +1297,11 @@ def main():
parser.add_argument("-p", "--bluetooth-pair", action="store_true", help="Put device into bluetooth pairing mode")
parser.add_argument("-D", "--display", action="store", metavar="i", type=int, default=None, help="Set display intensity (0-255)")
parser.add_argument("-t", "--timeout", action="store", metavar="s", type=int, default=None, help="Set display timeout in seconds, 0 to disable")
parser.add_argument("--display-addr", action="store", metavar="byte", type=str, default=None, help="Set display address as hex byte (00 - FF)")
parser.add_argument("--np", action="store", metavar="i", type=int, default=None, help="Set NeoPixel intensity (0-255)")
parser.add_argument("--freq", action="store", metavar="Hz", type=int, default=None, help="Frequency in Hz for TNC mode")
parser.add_argument("--bw", action="store", metavar="Hz", type=int, default=None, help="Bandwidth in Hz for TNC mode")
parser.add_argument("--txp", action="store", metavar="dBm", type=int, default=None, help="TX power in dBm for TNC mode")
@@ -1621,6 +1660,8 @@ def main():
print("[9] LilyGO LoRa T3S3")
print("[10] RAK4631")
print("[11] LilyGo T-Echo")
print("[12] LilyGO T-Beam Supreme")
print("[13] LilyGO T-Deck")
print(" .")
print(" / \\ Select one of these options if you want to easily turn")
print(" | a supported development board into an RNode.")
@@ -1632,7 +1673,7 @@ def main():
try:
c_dev = int(input())
c_mod = False
if c_dev < 1 or c_dev > 11:
if c_dev < 1 or c_dev > 13:
raise ValueError()
elif c_dev == 1:
selected_product = ROM.PRODUCT_RNODE
@@ -1669,6 +1710,38 @@ def main():
print("who would like to experiment with it. Hit enter to continue.")
print("---------------------------------------------------------------------------")
input()
elif c_dev == 12:
selected_product = ROM.PRODUCT_TBEAM_S_V1
clear()
print("")
print("---------------------------------------------------------------------------")
print(" T-Beam Supreme RNode Installer")
print("")
print("The RNode firmware can currently be installed on T-Beam Supreme devices")
print("using the SX1262 and SX1268 transceiver chips.")
print("")
print("Important! Using RNode firmware on T-Beam devices should currently be")
print("considered experimental. It is not intended for production or critical use.")
print("The currently supplied firmware is provided AS-IS as a courtesey to those")
print("who would like to experiment with it. Hit enter to continue.")
print("---------------------------------------------------------------------------")
input()
elif c_dev == 13:
selected_product = ROM.PRODUCT_TDECK
clear()
print("")
print("---------------------------------------------------------------------------")
print(" T-Deck RNode Installer")
print("")
print("The RNode firmware can currently be installed on T-Deck devices using the")
print("SX1262 and SX1268 transceiver chips.")
print("")
print("Important! Using RNode firmware on T-Beam devices should currently be")
print("considered experimental. It is not intended for production or critical use.")
print("The currently supplied firmware is provided AS-IS as a courtesey to those")
print("who would like to experiment with it. Hit enter to continue.")
print("---------------------------------------------------------------------------")
input()
elif c_dev == 4:
selected_product = ROM.PRODUCT_T32_20
clear()
@@ -1739,8 +1812,6 @@ def main():
print("Important! Using RNode firmware on T3S3 devices should currently be")
print("considered experimental. It is not intended for production or critical use.")
print("")
print("Please note that Bluetooth is currently not implemented on this board.")
print("")
print("The currently supplied firmware is provided AS-IS as a courtesey to those")
print("who would like to experiment with it. Hit enter to continue.")
print("---------------------------------------------------------------------------")
@@ -1755,8 +1826,6 @@ def main():
print("Important! Using RNode firmware on Heltec devices should currently be")
print("considered experimental. It is not intended for production or critical use.")
print("")
print("Please note that Bluetooth is currently not implemented on this board.")
print("")
print("The currently supplied firmware is provided AS-IS as a courtesey to those")
print("who would like to experiment with it. Hit enter to continue.")
print("---------------------------------------------------------------------------")
@@ -1889,19 +1958,30 @@ def main():
print("That model does not exist, exiting now.")
graceful_exit()
else:
print("\nWhat model is this T3S3?\n")
print("[1] 410 - 525 MHz (with SX1268 chip)")
print("[2] 820 - 1020 MHz (with SX1262 chip)")
print("\nWhat band is this T3S3 for?\n")
print("[1] 433 MHz (with SX1278 chip)")
print("[2] 868/915/923 MHz (with SX1276 chip)")
print("");
print("[3] 433 MHz (with SX1268 chip)")
print("[4] 868/915/923 MHz (with SX1262 chip)")
print("\n? ", end="")
try:
c_model = int(input())
if c_model < 1 or c_model > 2:
if c_model < 1 or c_model > 4:
raise ValueError()
elif c_model == 1:
selected_model = ROM.MODEL_A1
selected_model = ROM.MODEL_A5
selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 2:
selected_model = ROM.MODEL_AA
selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 3:
selected_model = ROM.MODEL_A1
selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 4:
selected_model = ROM.MODEL_A6
selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
@@ -1938,6 +2018,46 @@ def main():
print("That band does not exist, exiting now.")
graceful_exit()
elif selected_product == ROM.PRODUCT_TBEAM_S_V1:
selected_mcu = ROM.MCU_ESP32
print("\nWhat band is this T-Beam Supreme for?\n")
print("[1] 433 MHz (with SX1268 chip)")
print("[2] 868/915/923 MHz (with SX1262 chip)")
print("\n? ", end="")
try:
c_model = int(input())
if c_model < 1 or c_model > 2:
raise ValueError()
elif c_model == 1:
selected_model = ROM.MODEL_DB
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 2:
selected_model = ROM.MODEL_DC
selected_platform = ROM.PLATFORM_ESP32
except Exception as e:
print("That band does not exist, exiting now.")
graceful_exit()
elif selected_product == ROM.PRODUCT_TDECK:
selected_mcu = ROM.MCU_ESP32
print("\nWhat band is this T-Deck for?\n")
print("[1] 433 MHz (with SX1268 chip)")
print("[2] 868/915/923 MHz (with SX1262 chip)")
print("\n? ", end="")
try:
c_model = int(input())
if c_model < 1 or c_model > 2:
raise ValueError()
elif c_model == 1:
selected_model = ROM.MODEL_D4
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 2:
selected_model = ROM.MODEL_D9
selected_platform = ROM.PLATFORM_ESP32
except Exception as e:
print("That band does not exist, exiting now.")
graceful_exit()
elif selected_product == ROM.PRODUCT_T32_10:
selected_mcu = ROM.MCU_ESP32
print("\nWhat band is this LoRa32 for?\n")
@@ -2770,6 +2890,60 @@ def main():
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3.partitions",
]
elif fw_filename == "rnode_firmware_t3s3_sx127x.zip":
return [
sys.executable, flasher,
"--chip", "esp32s3",
"--port", args.port,
"--baud", args.baud_flash,
"--before", "default_reset",
"--after", "hard_reset",
"write_flash", "-z",
"--flash_mode", "dio",
"--flash_freq", "80m",
"--flash_size", "4MB",
"0xe000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3_sx127x.boot_app0",
"0x0", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3_sx127x.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3_sx127x.bin",
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3_sx127x.partitions",
]
elif fw_filename == "rnode_firmware_tbeam_supreme.zip":
return [
sys.executable, flasher,
"--chip", "esp32s3",
"--port", args.port,
"--baud", args.baud_flash,
"--before", "default_reset",
"--after", "hard_reset",
"write_flash", "-z",
"--flash_mode", "dio",
"--flash_freq", "80m",
"--flash_size", "4MB",
"0xe000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_supreme.boot_app0",
"0x0", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_supreme.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_supreme.bin",
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_supreme.partitions",
]
elif fw_filename == "rnode_firmware_tdeck.zip":
return [
sys.executable, flasher,
"--chip", "esp32s3",
"--port", args.port,
"--baud", args.baud_flash,
"--before", "default_reset",
"--after", "hard_reset",
"write_flash", "-z",
"--flash_mode", "dio",
"--flash_freq", "80m",
"--flash_size", "4MB",
"0xe000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tdeck.boot_app0",
"0x0", UPD_DIR+"/"+selected_version+"/rnode_firmware_tdeck.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tdeck.bin",
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tdeck.partitions",
]
elif fw_filename == "extracted_rnode_firmware.zip":
return [
sys.executable, flasher,
@@ -3168,6 +3342,27 @@ def main():
RNS.log("Setting display intensity to "+str(di))
rnode.set_display_intensity(di)
if isinstance(args.timeout, int):
di = args.timeout
if di < 0:
di = 0
if di > 255:
di = 255
if di == 0:
RNS.log("Disabling display blanking")
else:
RNS.log("Setting display timeout to "+str(di))
rnode.set_display_blanking(di)
if isinstance(args.np, int):
di = args.np
if di < 0:
di = 0
if di > 255:
di = 255
RNS.log("Setting NeoPixel intensity to "+str(di))
rnode.set_neopixel_intensity(di)
if isinstance(args.display_addr, str):
set_addr = False
try:
+17
View File
@@ -294,6 +294,23 @@ loglevel = 4
# Serial port for the device
port = /dev/ttyUSB0
# 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://
# Set frequency to 867.2 MHz
frequency = 867200000
+7
View File
@@ -292,6 +292,13 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
if "bitrate" in ifstat and ifstat["bitrate"] != None:
print(" Rate : {ss}".format(ss=speed_str(ifstat["bitrate"])))
if "battery_percent" in ifstat and ifstat["battery_percent"] != None:
try:
bpi = int(ifstat["battery_percent"])
print(" Battery : {bp}%".format(bp=bpi))
except:
pass
if "airtime_short" in ifstat and "airtime_long" in ifstat:
print(" Airtime : {ats}% (15s), {atl}% (1h)".format(ats=str(ifstat["airtime_short"]),atl=str(ifstat["airtime_long"])))
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.7.9"
__version__ = "0.8.2"
+11 -17
View File
@@ -14,15 +14,15 @@ This document outlines the currently established development roadmap for Reticul
## Currently Active Work Areas
For each release cycle of Reticulum, improvements and additions from the five [Primary Efforts](#primary-efforts) are selected as active work areas, and can be expected to be included in the upcoming releases within that cycle. While not entirely set in stone for each release cycle, they serve as a pointer of what to expect in the near future.
- The current `0.7.x` release cycle aims at completing
- [x] Automatic asynchronous key ratcheting for non-link traffic
- [ ] API improvements based on real-world usage and feedback
- The current `0.8.x` release cycle aims at completing
- [ ] Hot-pluggable interface system
- [ ] External interface plugins
- [ ] Network-wide path balancing and multi-pathing
- [ ] Expanded hardware support
- [ ] Overhauling and updating the documentation
- [ ] Distributed Destination Naming System
- [ ] Create a standalone RNS Daemon app for Android
- [ ] Network-wide path balancing
- [ ] Add automatic retries to all use cases of the `Request` API
- [ ] A standalone RNS Daemon app for Android
- [ ] Addding automatic retries to all use cases of the `Request` API
- [ ] Performance and memory optimisations of the Python reference implementation
- [ ] Fixing bugs discovered while operating Reticulum systems and applications
@@ -38,17 +38,9 @@ These efforts are aimed at improving the ease of which Reticulum is understood,
- Update announce description
- Add in-depth explanation of the IFAC system
- Software
- Update Sideband screenshots
- Update Sideband description
- Update NomadNet screenshots
- Update Sideband screenshots
- Installation
- [x] Add a *Reticulum On Raspberry Pi* section
- [x] Update *Reticulum On Android* section if necessary
- [x] Update Android install documentation.
- Update software descriptions and screenshots
- Communications hardware section
- Add information about RNode external displays.
- [x] Packet radio modems.
- Possibly add other relevant types here as well.
- Setup *Best Practices For...* / *Installation Examples* section.
- Home or office (example)
@@ -68,6 +60,8 @@ These efforts seek to broaden the universality of the Reticulum software and har
### Functionality
These efforts aim to expand and improve the core functionality and reliability of Reticulum.
- Add support for user-supplied external interface drivers
- Add interface hot-plug and live up/down control to running instances
- Add automatic retries to all use cases of the `Request` API
- Network-wide path balancing
- Distributed Destination Naming System
@@ -85,10 +79,10 @@ These effors seek to make Reticulum easier to use and operate, and to expand the
### Interfaceability
These efforts aim to expand the types of physical and virtual interfaces that Reticulum can natively use to transport data.
- Filesystem interface
- Plain ESP32 devices (ESP-Now, WiFi, Bluetooth, etc.)
- More LoRa transceivers
- AT-compatible modems
- Filesystem interface
- Direct SDR Support
- Optical mediums
- IR Transceivers
@@ -108,7 +102,7 @@ The Reticulum ecosystem is enriched by several other software and hardware proje
This section lists, in no particular order, various important efforts that would be beneficial to the goals of Reticulum.
- The [RNode](https://unsigned.io/rnode/) project
- [ ] Create a WebUSB-based bootstrapping utility, and integrate this directly into the [RNode Bootstrap Console](#), both on-device, and on an Internet-reachable copy. This will make it much easier to create new RNodes for average users.
- [x] Create a WebUSB-based bootstrapping utility, and integrate this directly into the [RNode Bootstrap Console](#), both on-device, and on an Internet-reachable copy. This will make it much easier to create new RNodes for average users.
## Release History
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: e961aac7a90a0d0a4e76d715c5160afc
config: bd0a676b0f490cda5d841ab7cd7cade1
tags: 645f666f9bcd5a90fca523b33c5a78b7

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

+118 -46
View File
@@ -90,77 +90,151 @@ Supported Boards
To create one or more RNodes, you will need to obtain supported development
boards. The following boards are supported by the auto-installer.
LilyGO LoRa32 v2.1
""""""""""""""""""
.. image:: graphics/board_t3v21.png
:width: 46%
------------
.. image:: graphics/board_tbeam_supreme.png
:width: 75%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
LilyGO LoRa32 v2.0
""""""""""""""""""
.. image:: graphics/board_t3v20.png
:width: 46%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
LilyGO T-Beam
LilyGO T-Beam Supreme
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_tbeam.png
:width: 75%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
LilyGO T-Beam
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
Heltec LoRa32 v2.0
""""""""""""""""""
.. image:: graphics/board_heltec32.png
:width: 58%
.. image:: graphics/board_t3s3.png
:width: 50%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
LilyGO T3S3
"""""""""""
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_rak4631.png
:width: 45%
:align: center
RAK4631-based Boards
""""""""""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268
- **Device Platform** nRF52
- **Manufacturer** `RAK Wireless <https://www.rakwireless.com>`_
------------
.. image:: graphics/board_rnodev2.png
:width: 68%
:align: center
Unsigned RNode v2.x
"""""""""""""""""""
.. image:: graphics/board_rnodev2.png
:width: 58%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `unsigned.io <https://unsigned.io>`_
------------
.. image:: graphics/board_t3v21.png
:width: 46%
:align: center
LilyGO LoRa32 v2.1
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_t3v20.png
:width: 46%
:align: center
LilyGO LoRa32 v2.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_t3v10.png
:width: 46%
:align: center
LilyGO LoRa32 v1.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_tdeck.png
:width: 45%
:align: center
LilyGO T-Deck
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_heltec32v30.png
:width: 58%
:align: center
Heltec LoRa32 v3.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1262 and SX1268
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
------------
.. image:: graphics/board_heltec32v20.png
:width: 58%
:align: center
Heltec LoRa32 v2.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
------------
Unsigned RNode v1.x
"""""""""""""""""""
.. image:: graphics/board_rnode.png
:width: 50%
:align: center
- **Supported Firmware Lines** v1.x
- **Transceiver IC** Semtech SX1276
Unsigned RNode v1.x
"""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** AVR ATmega1284p
- **Manufacturer** `unsigned.io <https://unsigned.io>`_
------------
.. _rnode-installation:
@@ -194,10 +268,8 @@ Usage with Reticulum
^^^^^^^^^^^^^^^^^^^^
When the devices have been installed and provisioned, you can use them with Reticulum
by adding the :ref:`relevant interface section<interfaces-rnode>` to the configuration
file of Reticulum. For v1.x firmwares, you will have to specify all interface parameters,
such as serial port and on-air parameters. For v2.x firmwares, you just need to specify
the Connection ID of the RNode, and Reticulum will automatically locate and connect to the
RNode, using the parameters stored in the RNode itself.
file of Reticulum. In the configuraion you can specify all interface parameters,
such as serial port and on-air parameters.
WiFi-based Hardware
+17
View File
@@ -358,6 +358,23 @@ can be used, and offers full control over LoRa parameters.
# Serial port for the device
port = /dev/ttyUSB0
# 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://
# Set frequency to 867.2 MHz
frequency = 867200000
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.7.9 beta',
VERSION: '0.8.2 beta',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Support Reticulum" href="support.html" /><link rel="prev" title="Building Networks" href="networks.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Code Examples - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Code Examples - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.7.9 beta documentation</title>
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -139,7 +139,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -165,7 +165,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Using Reticulum on Your System" href="using.html" /><link rel="prev" title="What is Reticulum?" href="whatis.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Getting Started Fast - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Getting Started Fast - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+104 -39
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Configuring Interfaces" href="interfaces.html" /><link rel="prev" title="Understanding Reticulum" href="understanding.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Communications Hardware - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Communications Hardware - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -291,65 +291,126 @@ to the configuration.</p>
<span id="rnode-supported"></span><h3>Supported Boards<a class="headerlink" href="#supported-boards" title="Permalink to this heading">#</a></h3>
<p>To create one or more RNodes, you will need to obtain supported development
boards. The following boards are supported by the auto-installer.</p>
<section id="lilygo-lora32-v2-1">
<h4>LilyGO LoRa32 v2.1<a class="headerlink" href="#lilygo-lora32-v2-1" title="Permalink to this heading">#</a></h4>
<a class="reference internal image-reference" href="_images/board_t3v21.png"><img alt="_images/board_t3v21.png" class="align-center" src="_images/board_t3v21.png" style="width: 46%;" /></a>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_tbeam_supreme.png"><img alt="_images/board_tbeam_supreme.png" class="align-center" src="_images/board_tbeam_supreme.png" style="width: 75%;" /></a>
<section id="lilygo-t-beam-supreme">
<h4>LilyGO T-Beam Supreme<a class="headerlink" href="#lilygo-t-beam-supreme" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Supported Firmware Lines</strong> v1.x &amp; v2.x</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
</section>
<section id="lilygo-lora32-v2-0">
<h4>LilyGO LoRa32 v2.0<a class="headerlink" href="#lilygo-lora32-v2-0" title="Permalink to this heading">#</a></h4>
<a class="reference internal image-reference" href="_images/board_t3v20.png"><img alt="_images/board_t3v20.png" class="align-center" src="_images/board_t3v20.png" style="width: 46%;" /></a>
<ul class="simple">
<li><p><strong>Supported Firmware Lines</strong> v1.x &amp; v2.x</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1262, SX1268</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_tbeam.png"><img alt="_images/board_tbeam.png" class="align-center" src="_images/board_tbeam.png" style="width: 75%;" /></a>
</section>
<section id="lilygo-t-beam">
<h4>LilyGO T-Beam<a class="headerlink" href="#lilygo-t-beam" title="Permalink to this heading">#</a></h4>
<a class="reference internal image-reference" href="_images/board_tbeam.png"><img alt="_images/board_tbeam.png" class="align-center" src="_images/board_tbeam.png" style="width: 75%;" /></a>
<ul class="simple">
<li><p><strong>Supported Firmware Lines</strong> v1.x &amp; v2.x</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1262, SX1268, SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_t3s3.png"><img alt="_images/board_t3s3.png" class="align-center" src="_images/board_t3s3.png" style="width: 50%;" /></a>
</section>
<section id="heltec-lora32-v2-0">
<h4>Heltec LoRa32 v2.0<a class="headerlink" href="#heltec-lora32-v2-0" title="Permalink to this heading">#</a></h4>
<a class="reference internal image-reference" href="_images/board_heltec32.png"><img alt="_images/board_heltec32.png" class="align-center" src="_images/board_heltec32.png" style="width: 58%;" /></a>
<section id="lilygo-t3s3">
<h4>LilyGO T3S3<a class="headerlink" href="#lilygo-t3s3" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Supported Firmware Lines</strong> v1.x &amp; v2.x</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1262, SX1268, SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://heltec.org">Heltec Automation</a></p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_rak4631.png"><img alt="_images/board_rak4631.png" class="align-center" src="_images/board_rak4631.png" style="width: 45%;" /></a>
</section>
<section id="rak4631-based-boards">
<h4>RAK4631-based Boards<a class="headerlink" href="#rak4631-based-boards" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1262, SX1268</p></li>
<li><p><strong>Device Platform</strong> nRF52</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://www.rakwireless.com">RAK Wireless</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_rnodev2.png"><img alt="_images/board_rnodev2.png" class="align-center" src="_images/board_rnodev2.png" style="width: 68%;" /></a>
</section>
<section id="unsigned-rnode-v2-x">
<h4>Unsigned RNode v2.x<a class="headerlink" href="#unsigned-rnode-v2-x" title="Permalink to this heading">#</a></h4>
<a class="reference internal image-reference" href="_images/board_rnodev2.png"><img alt="_images/board_rnodev2.png" class="align-center" src="_images/board_rnodev2.png" style="width: 58%;" /></a>
<ul class="simple">
<li><p><strong>Supported Firmware Lines</strong> v1.x &amp; v2.x</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://unsigned.io">unsigned.io</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_t3v21.png"><img alt="_images/board_t3v21.png" class="align-center" src="_images/board_t3v21.png" style="width: 46%;" /></a>
</section>
<section id="lilygo-lora32-v2-1">
<h4>LilyGO LoRa32 v2.1<a class="headerlink" href="#lilygo-lora32-v2-1" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_t3v20.png"><img alt="_images/board_t3v20.png" class="align-center" src="_images/board_t3v20.png" style="width: 46%;" /></a>
</section>
<section id="lilygo-lora32-v2-0">
<h4>LilyGO LoRa32 v2.0<a class="headerlink" href="#lilygo-lora32-v2-0" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_t3v10.png"><img alt="_images/board_t3v10.png" class="align-center" src="_images/board_t3v10.png" style="width: 46%;" /></a>
</section>
<section id="lilygo-lora32-v1-0">
<h4>LilyGO LoRa32 v1.0<a class="headerlink" href="#lilygo-lora32-v1-0" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_tdeck.png"><img alt="_images/board_tdeck.png" class="align-center" src="_images/board_tdeck.png" style="width: 45%;" /></a>
</section>
<section id="lilygo-t-deck">
<h4>LilyGO T-Deck<a class="headerlink" href="#lilygo-t-deck" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1262, SX1268</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://lilygo.cn">LilyGO</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_heltec32v30.png"><img alt="_images/board_heltec32v30.png" class="align-center" src="_images/board_heltec32v30.png" style="width: 58%;" /></a>
</section>
<section id="heltec-lora32-v3-0">
<h4>Heltec LoRa32 v3.0<a class="headerlink" href="#heltec-lora32-v3-0" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1262 and SX1268</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://heltec.org">Heltec Automation</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_heltec32v20.png"><img alt="_images/board_heltec32v20.png" class="align-center" src="_images/board_heltec32v20.png" style="width: 58%;" /></a>
</section>
<section id="heltec-lora32-v2-0">
<h4>Heltec LoRa32 v2.0<a class="headerlink" href="#heltec-lora32-v2-0" title="Permalink to this heading">#</a></h4>
<ul class="simple">
<li><p><strong>Transceiver IC</strong> Semtech SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> ESP32</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://heltec.org">Heltec Automation</a></p></li>
</ul>
<hr class="docutils" />
<a class="reference internal image-reference" href="_images/board_rnode.png"><img alt="_images/board_rnode.png" class="align-center" src="_images/board_rnode.png" style="width: 50%;" /></a>
</section>
<section id="unsigned-rnode-v1-x">
<h4>Unsigned RNode v1.x<a class="headerlink" href="#unsigned-rnode-v1-x" title="Permalink to this heading">#</a></h4>
<a class="reference internal image-reference" href="_images/board_rnode.png"><img alt="_images/board_rnode.png" class="align-center" src="_images/board_rnode.png" style="width: 50%;" /></a>
<ul class="simple">
<li><p><strong>Supported Firmware Lines</strong> v1.x</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276</p></li>
<li><p><strong>Transceiver IC</strong> Semtech SX1276 and SX1278</p></li>
<li><p><strong>Device Platform</strong> AVR ATmega1284p</p></li>
<li><p><strong>Manufacturer</strong> <a class="reference external" href="https://unsigned.io">unsigned.io</a></p></li>
</ul>
<hr class="docutils" />
</section>
</section>
<section id="installation">
@@ -375,10 +436,8 @@ auto-install and configure your devices.</p>
<span id="rnode-usage"></span><h3>Usage with Reticulum<a class="headerlink" href="#usage-with-reticulum" title="Permalink to this heading">#</a></h3>
<p>When the devices have been installed and provisioned, you can use them with Reticulum
by adding the <a class="reference internal" href="interfaces.html#interfaces-rnode"><span class="std std-ref">relevant interface section</span></a> to the configuration
file of Reticulum. For v1.x firmwares, you will have to specify all interface parameters,
such as serial port and on-air parameters. For v2.x firmwares, you just need to specify
the Connection ID of the RNode, and Reticulum will automatically locate and connect to the
RNode, using the parameters stored in the RNode itself.</p>
file of Reticulum. In the configuraion you can specify all interface parameters,
such as serial port and on-air parameters.</p>
</section>
</section>
<section id="wifi-based-hardware">
@@ -492,11 +551,17 @@ can be used with Reticulum. This includes virtual software modems such as
<li><a class="reference internal" href="#rnode">RNode</a><ul>
<li><a class="reference internal" href="#creating-rnodes">Creating RNodes</a></li>
<li><a class="reference internal" href="#supported-boards">Supported Boards</a><ul>
<li><a class="reference internal" href="#lilygo-t-beam-supreme">LilyGO T-Beam Supreme</a></li>
<li><a class="reference internal" href="#lilygo-t-beam">LilyGO T-Beam</a></li>
<li><a class="reference internal" href="#lilygo-t3s3">LilyGO T3S3</a></li>
<li><a class="reference internal" href="#rak4631-based-boards">RAK4631-based Boards</a></li>
<li><a class="reference internal" href="#unsigned-rnode-v2-x">Unsigned RNode v2.x</a></li>
<li><a class="reference internal" href="#lilygo-lora32-v2-1">LilyGO LoRa32 v2.1</a></li>
<li><a class="reference internal" href="#lilygo-lora32-v2-0">LilyGO LoRa32 v2.0</a></li>
<li><a class="reference internal" href="#lilygo-t-beam">LilyGO T-Beam</a></li>
<li><a class="reference internal" href="#lilygo-lora32-v1-0">LilyGO LoRa32 v1.0</a></li>
<li><a class="reference internal" href="#lilygo-t-deck">LilyGO T-Deck</a></li>
<li><a class="reference internal" href="#heltec-lora32-v3-0">Heltec LoRa32 v3.0</a></li>
<li><a class="reference internal" href="#heltec-lora32-v2-0">Heltec LoRa32 v2.0</a></li>
<li><a class="reference internal" href="#unsigned-rnode-v2-x">Unsigned RNode v2.x</a></li>
<li><a class="reference internal" href="#unsigned-rnode-v1-x">Unsigned RNode v1.x</a></li>
</ul>
</li>
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="What is Reticulum?" href="whatis.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="#"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="#"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+20 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Building Networks" href="networks.html" /><link rel="prev" title="Communications Hardware" href="hardware.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Configuring Interfaces - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Configuring Interfaces - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -520,6 +520,23 @@ can be used, and offers full control over LoRa parameters.</p>
<span class="c1"># Serial port for the device</span>
<span class="n">port</span> <span class="o">=</span> <span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">ttyUSB0</span>
<span class="c1"># It is also possible to use BLE devices</span>
<span class="c1"># instead of wired serial ports. The</span>
<span class="c1"># target RNode must be paired with the</span>
<span class="c1"># host device before connecting. BLE</span>
<span class="c1"># devices can be connected by name,</span>
<span class="c1"># BLE MAC address or by any available.</span>
<span class="c1"># Connect to specific device by name</span>
<span class="c1"># port = ble://RNode 3B87</span>
<span class="c1"># Or by BLE MAC address</span>
<span class="c1"># port = ble://F4:12:73:29:4E:89</span>
<span class="c1"># Or connect to the first available,</span>
<span class="c1"># paired device</span>
<span class="c1"># port = ble://</span>
<span class="c1"># Set frequency to 867.2 MHz</span>
<span class="n">frequency</span> <span class="o">=</span> <span class="mi">867200000</span>
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Code Examples" href="examples.html" /><link rel="prev" title="Configuring Interfaces" href="interfaces.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Building Networks - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Building Networks - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
Binary file not shown.
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="Support Reticulum" href="support.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>API Reference - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>API Reference - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="#" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Search - Reticulum Network Stack 0.7.9 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Search - Reticulum Network Stack 0.8.2 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@@ -138,7 +138,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -164,7 +164,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="#" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="API Reference" href="reference.html" /><link rel="prev" title="Code Examples" href="examples.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Support Reticulum - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Support Reticulum - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Communications Hardware" href="hardware.html" /><link rel="prev" title="Using Reticulum on Your System" href="using.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Understanding Reticulum - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Understanding Reticulum - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Understanding Reticulum" href="understanding.html" /><link rel="prev" title="Getting Started Fast" href="gettingstartedfast.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Getting Started Fast" href="gettingstartedfast.html" /><link rel="prev" title="Reticulum Network Stack Manual" href="index.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/>
<title>What is Reticulum? - Reticulum Network Stack 0.7.9 beta documentation</title>
<title>What is Reticulum? - Reticulum Network Stack 0.8.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.7.9 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.2 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.7.9 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+118 -46
View File
@@ -90,77 +90,151 @@ Supported Boards
To create one or more RNodes, you will need to obtain supported development
boards. The following boards are supported by the auto-installer.
LilyGO LoRa32 v2.1
""""""""""""""""""
.. image:: graphics/board_t3v21.png
:width: 46%
------------
.. image:: graphics/board_tbeam_supreme.png
:width: 75%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
LilyGO LoRa32 v2.0
""""""""""""""""""
.. image:: graphics/board_t3v20.png
:width: 46%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
LilyGO T-Beam
LilyGO T-Beam Supreme
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_tbeam.png
:width: 75%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
LilyGO T-Beam
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
Heltec LoRa32 v2.0
""""""""""""""""""
.. image:: graphics/board_heltec32.png
:width: 58%
.. image:: graphics/board_t3s3.png
:width: 50%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
LilyGO T3S3
"""""""""""
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_rak4631.png
:width: 45%
:align: center
RAK4631-based Boards
""""""""""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268
- **Device Platform** nRF52
- **Manufacturer** `RAK Wireless <https://www.rakwireless.com>`_
------------
.. image:: graphics/board_rnodev2.png
:width: 68%
:align: center
Unsigned RNode v2.x
"""""""""""""""""""
.. image:: graphics/board_rnodev2.png
:width: 58%
:align: center
- **Supported Firmware Lines** v1.x & v2.x
- **Transceiver IC** Semtech SX1276
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `unsigned.io <https://unsigned.io>`_
------------
.. image:: graphics/board_t3v21.png
:width: 46%
:align: center
LilyGO LoRa32 v2.1
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_t3v20.png
:width: 46%
:align: center
LilyGO LoRa32 v2.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_t3v10.png
:width: 46%
:align: center
LilyGO LoRa32 v1.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_tdeck.png
:width: 45%
:align: center
LilyGO T-Deck
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
------------
.. image:: graphics/board_heltec32v30.png
:width: 58%
:align: center
Heltec LoRa32 v3.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1262 and SX1268
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
------------
.. image:: graphics/board_heltec32v20.png
:width: 58%
:align: center
Heltec LoRa32 v2.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
------------
Unsigned RNode v1.x
"""""""""""""""""""
.. image:: graphics/board_rnode.png
:width: 50%
:align: center
- **Supported Firmware Lines** v1.x
- **Transceiver IC** Semtech SX1276
Unsigned RNode v1.x
"""""""""""""""""""
- **Transceiver IC** Semtech SX1276 and SX1278
- **Device Platform** AVR ATmega1284p
- **Manufacturer** `unsigned.io <https://unsigned.io>`_
------------
.. _rnode-installation:
@@ -194,10 +268,8 @@ Usage with Reticulum
^^^^^^^^^^^^^^^^^^^^
When the devices have been installed and provisioned, you can use them with Reticulum
by adding the :ref:`relevant interface section<interfaces-rnode>` to the configuration
file of Reticulum. For v1.x firmwares, you will have to specify all interface parameters,
such as serial port and on-air parameters. For v2.x firmwares, you just need to specify
the Connection ID of the RNode, and Reticulum will automatically locate and connect to the
RNode, using the parameters stored in the RNode itself.
file of Reticulum. In the configuraion you can specify all interface parameters,
such as serial port and on-air parameters.
WiFi-based Hardware
+17
View File
@@ -358,6 +358,23 @@ can be used, and offers full control over LoRa parameters.
# Serial port for the device
port = /dev/ttyUSB0
# 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://
# Set frequency to 867.2 MHz
frequency = 867200000
-1
View File
@@ -10,7 +10,6 @@ if '--pure' in sys.argv:
print("Building pure-python wheel")
exec(open("RNS/_version.py", "r").read())
with open("README.md", "r") as fh:
long_description = fh.read()