Compare commits

...

49 Commits

Author SHA1 Message Date
Mark Qvist 30248854ed Updated changelog 2024-10-11 17:13:03 +02:00
Mark Qvist f34bc75588 Updated docs 2024-10-11 16:47:53 +02:00
Mark Qvist 3b23e2f37d Improved RNode BLE reconnection reliability 2024-10-11 13:38:16 +02:00
Mark Qvist 7417cf5947 Add rnode battery state to rnstatus output 2024-10-11 10:14:10 +02:00
Mark Qvist 60d8da843c Disable tty module dependency for rnx, since it is currently unused 2024-10-11 09:54:09 +02:00
Mark Qvist f9667fd684 Fixed missing import on Android 2024-10-10 23:49:20 +02:00
Mark Qvist d9269c6047 Updated version 2024-10-10 23:32:09 +02:00
Mark Qvist 6521f839cd Fixed resource transfers hanging for a long time over slow links if proof packet is lost 2024-10-10 17:06:43 +02:00
Mark Qvist d63bbcdc0a Updated changelog 2024-10-10 00:45:09 +02:00
Mark Qvist c36c7186de Updated docs 2024-10-10 00:44:33 +02:00
Mark Qvist 6fec76205c Added save directory option to rncp 2024-10-10 00:41:57 +02:00
Mark Qvist 715f4d9fcb Updated version 2024-10-09 20:03:05 +02:00
Mark Qvist 8d7857c4e2 Fixed rncp fstrings for Android build 2024-10-09 19:53:07 +02:00
Mark Qvist c9a2b45368 Added physical layer transfer rate output option to rncp 2024-10-09 19:39:39 +02:00
Mark Qvist c57d927660 Cleanup 2024-10-09 19:38:46 +02:00
Mark Qvist 8d98c8751a Fixed resource progress calculation bug. Actually fixes #522. 2024-10-09 19:38:25 +02:00
Mark Qvist 527f6cc906 Fuxed typo 2024-10-07 22:10:17 +02:00
Mark Qvist a0d61f6441 Added error descriptions for modem communication timeout 2024-10-07 20:55:34 +02:00
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
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
Pavol Rusnak 43d8fdb423 docs: add Heltec LoRa32 v3.0 and LilyGO LoRa32 v1.0 to hardware 2024-09-29 11:51:43 +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
57 changed files with 971 additions and 289 deletions
+62 -1
View File
@@ -1,6 +1,67 @@
### 2024-10-11: RNS β 0.8.4
This release fixes a number of bugs and improves reliability of automatic reconnection when BLE-connected RNodes unexpectedly disappear or lose connection.
**Changes**
- Improved RNode BLE reconnection realiability
- Added RNode battery state to `rnstatus` output
- Fixed resource transfer hanging for a long time over slow links if proof packet is lost
- Fixed missing import on Android
**Release Hashes**
```
d3f7a9fddc6c1e59b1e4895756fe602408ac6ef09de377ee65ec62d09fff97a3 dist/rns-0.8.4-py3-none-any.whl
eb3843bcab1428be0adb097988991229a4c03156ab40cc9c6e2d9c590d8b850b dist/rnspure-0.8.4-py3-none-any.whl
```
### 2024-10-10: RNS β 0.8.3
This release fixes a bug in resource transfer progress calculation, improves RNode error handling, and brings minor improvements to the `rncp` utility.
**Changes**
- Fixed a bug in resource transfer progress calculations
- Added physical layer transfer rate output option to `rncp`
- Added save directory option to `rncp`
- Improved path handling for the fetch-jail option of of `rncp`
- Added error detection for modem communication timeouts on connected RNode devices
**Release Hashes**
```
54ddab32769081045db5fe45b27492cc012bf2fad64bc65ed37011f3651469fb rns-0.8.3-py3-none-any.whl
a04915111d65b05a5f2ef2687ed208813034196c0c5e711cb01e6db72faa23ef rnspure-0.8.3-py3-none-any.whl
```
### 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 add BLE support to RNodeInterface, and support for configuring additional options to `rnodeconf`.
This release adds BLE support to RNodeInterface, and support for configuring additional options to `rnodeconf`.
**Changes**
- Added Bluetooth Low Energy support to RNodeInterface
+19 -3
View File
@@ -28,8 +28,14 @@ import time
import math
import RNS
from able import BluetoothDispatcher, GATT_SUCCESS
from able.adapter import require_bluetooth_enabled
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
@@ -81,11 +87,15 @@ class KISS():
ERROR_INITRADIO = 0x01
ERROR_TXFAILED = 0x02
ERROR_EEPROM_LOCKED = 0x03
ERROR_QUEUE_FULL = 0x04
ERROR_MEMORY_LOW = 0x05
ERROR_MODEM_TIMEOUT = 0x06
ERROR_INVALID_FIRMWARE = 0x10
ERROR_INVALID_BLE_MTU = 0x20
PLATFORM_AVR = 0x90
PLATFORM_ESP32 = 0x80
PLATFORM_NRF52 = 0x70
@staticmethod
def escape(data):
@@ -652,7 +662,7 @@ class RNodeInterface(Interface):
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:
@@ -1242,6 +1252,12 @@ 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"})
elif (byte == KISS.ERROR_MODEM_TIMEOUT):
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+"): Modem communication timed out", RNS.LOG_ERROR)
self.hw_errors.append({"error": KISS.ERROR_MODEM_TIMEOUT, "description": "Modem communication timed out on connected device"})
else:
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+")", RNS.LOG_ERROR)
raise IOError("Unknown hardware failure")
+1 -1
View File
@@ -176,8 +176,8 @@ class LocalClientInterface(Interface):
self.send_lock = Lock()
with self.send_lock:
# RNS.log(f"Simulating latency of {RNS.prettytime(s)} for {len(data)} bytes", RNS.LOG_EXTREME)
s = len(data) / self.bitrate * 8
RNS.log(f"Simulating latency of {RNS.prettytime(s)} for {len(data)} bytes")
time.sleep(s)
data = bytes([HDLC.FLAG])+HDLC.escape(data)+bytes([HDLC.FLAG])
+61 -9
View File
@@ -78,9 +78,13 @@ class KISS():
ERROR_INITRADIO = 0x01
ERROR_TXFAILED = 0x02
ERROR_EEPROM_LOCKED = 0x03
ERROR_QUEUE_FULL = 0x04
ERROR_MEMORY_LOW = 0x05
ERROR_MODEM_TIMEOUT = 0x06
PLATFORM_AVR = 0x90
PLATFORM_ESP32 = 0x80
PLATFORM_NRF52 = 0x70
@staticmethod
def escape(data):
@@ -286,6 +290,11 @@ class RNodeInterface(Interface):
else:
RNS.log(f"Opening BLE connection for {self}...")
if self.ble != None and self.ble.running == False:
self.ble.close()
self.ble.cleanup()
self.ble = None
if self.ble == None:
self.ble = BLEConnection(owner=self, target_name=self.ble_name, target_bt_addr=self.ble_addr)
self.serial = self.ble
@@ -294,8 +303,7 @@ class RNodeInterface(Interface):
while not self.ble.connected and time.time() < open_time + self.ble.CONNECT_TIMEOUT:
time.sleep(1)
def configure_device(self):
def reset_radio_state(self):
self.r_frequency = None
self.r_bandwidth = None
self.r_txpower = None
@@ -303,6 +311,10 @@ class RNodeInterface(Interface):
self.r_cr = None
self.r_state = None
self.r_lock = None
self.detected = False
def configure_device(self):
self.reset_radio_state()
sleep(2.0)
thread = threading.Thread(target=self.readLoop)
@@ -326,7 +338,7 @@ class RNodeInterface(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")
@@ -491,9 +503,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
@@ -506,7 +521,14 @@ class RNodeInterface(Interface):
def validateRadioState(self):
RNS.log("Waiting for radio configuration validation for "+str(self)+"...", RNS.LOG_VERBOSE)
sleep(0.25);
if self.use_ble:
sleep(1.00)
else:
sleep(0.25)
if self.use_ble and self.ble != None and self.ble.device_disappeared:
RNS.log(f"Device disappeared during radio state validation for {self}", RNS.LOG_ERROR)
return False
self.validcfg = True
if (self.r_frequency != None and abs(self.frequency - int(self.r_frequency)) > 100):
@@ -841,6 +863,12 @@ 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"})
elif (byte == KISS.ERROR_MODEM_TIMEOUT):
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+"): Modem communication timed out", RNS.LOG_ERROR)
self.hw_errors.append({"error": KISS.ERROR_MODEM_TIMEOUT, "description": "Modem communication timed out on connected device"})
else:
RNS.log(str(self)+" hardware error (code "+RNS.hexrep(byte)+")", RNS.LOG_ERROR)
raise IOError("Unknown hardware failure")
@@ -997,11 +1025,13 @@ class BLEConnection():
self.target_bt_addr = target_bt_addr
self.scan_timeout = BLEConnection.SCAN_TIMEOUT
self.ble_device = None
self.last_client = None
self.connected = False
self.running = False
self.should_run = False
self.must_disconnect = False
self.connect_job_running = False
self.device_disappeared = False
import importlib
if BLEConnection.bleak == None:
@@ -1019,8 +1049,17 @@ class BLEConnection():
self.should_run = True
self.connection_thread = threading.Thread(target=self.connection_job, daemon=True).start()
def cleanup(self):
try:
if self.last_client != None:
self.asyncio.run(self.last_client.disconnect())
except Exception as e:
RNS.log(f"Error while disconnecting BLE device on cleanup for {self.owner}", RNS.LOG_ERROR)
self.should_run = False
def connection_job(self):
while (self.should_run):
while self.should_run:
if self.ble_device == None:
self.ble_device = self.find_target_device()
@@ -1030,6 +1069,10 @@ class BLEConnection():
time.sleep(1)
self.cleanup()
self.running = False
RNS.log(f"BLE connection job for {self.owner} ended", RNS.LOG_DEBUG)
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)
@@ -1043,6 +1086,7 @@ class BLEConnection():
self.connected = True
self.ble_device = ble_client
self.last_client = ble_client
self.owner.port = str(f"ble://{ble_client.address}")
loop = self.asyncio.get_running_loop()
@@ -1064,12 +1108,14 @@ class BLEConnection():
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
self.device_disappeared = True
def find_target_device(self):
RNS.log(f"Searching for attachable BLE device for {self.owner}...", RNS.LOG_EXTREME)
@@ -1093,7 +1139,13 @@ class BLEConnection():
return False
device = self.asyncio.run(self.bleak.BleakScanner.find_device_by_filter(device_filter, timeout=self.scan_timeout))
device = None
try:
device = self.asyncio.run(self.bleak.BleakScanner.find_device_by_filter(device_filter, timeout=self.scan_timeout))
except Exception as e:
RNS.log(f"Error while finding BLE device for {self.owner}: {e}", RNS.LOG_ERROR)
self.should_run = False
return device
def device_bonded(self, device):
+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
+85 -12
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.
@@ -105,6 +118,7 @@ class Resource:
PART_TIMEOUT_FACTOR = 4
PART_TIMEOUT_FACTOR_AFTER_RTT = 2
PROOF_TIMEOUT_FACTOR = 3
MAX_RETRIES = 16
MAX_ADV_RETRIES = 4
SENDER_GRACE_TIME = 10.0
@@ -147,7 +161,7 @@ class Resource:
resource.encrypted = True if resource.flags & 0x01 else False
resource.compressed = True if resource.flags >> 1 & 0x01 else False
resource.initiator = False
resource.callback = callback
resource.callback = callback
resource.__progress_callback = progress_callback
resource.total_parts = int(math.ceil(resource.size/float(Resource.SDU)))
resource.received_count = 0
@@ -220,7 +234,6 @@ class Resource:
data_size = os.stat(data.name).st_size
self.total_size = data_size
self.grand_total_parts = math.ceil(data_size/Resource.SDU)
if data_size <= Resource.MAX_EFFICIENT_SIZE:
self.total_segments = 1
@@ -241,7 +254,6 @@ class Resource:
elif isinstance(data, bytes):
data_size = len(data)
self.grand_total_parts = math.ceil(data_size/Resource.SDU)
self.total_size = data_size
resource_data = data
@@ -275,6 +287,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
@@ -334,6 +347,7 @@ class Resource:
self.size = len(self.data)
self.sent_parts = 0
hashmap_entries = int(math.ceil(self.size/float(Resource.SDU)))
self.total_parts = hashmap_entries
hashmap_ok = False
while not hashmap_ok:
@@ -519,6 +533,10 @@ class Resource:
sleep_time = 0.001
elif self.status == Resource.AWAITING_PROOF:
# Decrease timeout factor since proof packets are
# significantly smaller than full req/resp roundtrip
self.timeout_factor = Resource.PROOF_TIMEOUT_FACTOR
sleep_time = self.last_part_sent + (self.rtt*self.timeout_factor+self.sender_grace_time) - time.time()
if sleep_time < 0:
if self.retries_left <= 0:
@@ -610,6 +628,7 @@ class Resource:
proof_data = self.hash+proof
proof_packet = RNS.Packet(self.link, proof_data, packet_type=RNS.Packet.PROOF, context=RNS.Packet.RESOURCE_PRF)
proof_packet.send()
RNS.Transport.cache(proof_packet, force_cache=True)
except Exception as e:
RNS.log("Could not send proof packet, cancelling resource", RNS.LOG_DEBUG)
RNS.log("The contained exception was: "+str(e), RNS.LOG_DEBUG)
@@ -759,6 +778,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
@@ -900,6 +925,7 @@ class Resource:
if self.sent_parts == len(self.parts):
self.status = Resource.AWAITING_PROOF
self.retries_left = 3
if self.__progress_callback != None:
try:
@@ -943,21 +969,68 @@ class Resource:
"""
if self.status == RNS.Resource.COMPLETE and self.segment_index == self.total_segments:
return 1.0
elif self.initiator:
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
self.processed_parts += self.sent_parts
self.progress_total_parts = float(self.grand_total_parts)
else:
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
self.processed_parts += self.received_count
if self.split:
self.progress_total_parts = float(math.ceil(self.total_size/Resource.SDU))
else:
if not self.split:
self.processed_parts = self.sent_parts
self.progress_total_parts = float(self.total_parts)
else:
is_last_segment = self.segment_index != self.total_segments
total_segments = self.total_segments
processed_segments = self.segment_index-1
current_segment_parts = self.total_parts
max_parts_per_segment = math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
previously_processed_parts = processed_segments*max_parts_per_segment
if current_segment_parts < max_parts_per_segment:
current_segment_factor = max_parts_per_segment / current_segment_parts
else:
current_segment_factor = 1
self.processed_parts = previously_processed_parts + self.sent_parts*current_segment_factor
self.progress_total_parts = self.total_segments*max_parts_per_segment
else:
if not self.split:
self.processed_parts = self.received_count
self.progress_total_parts = float(self.total_parts)
else:
is_last_segment = self.segment_index != self.total_segments
total_segments = self.total_segments
processed_segments = self.segment_index-1
current_segment_parts = self.total_parts
max_parts_per_segment = math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
previously_processed_parts = processed_segments*max_parts_per_segment
if current_segment_parts < max_parts_per_segment:
current_segment_factor = max_parts_per_segment / current_segment_parts
else:
current_segment_factor = 1
self.processed_parts = previously_processed_parts + self.received_count*current_segment_factor
self.progress_total_parts = self.total_segments*max_parts_per_segment
progress = min(1.0, self.processed_parts / self.progress_total_parts)
return progress
def get_segment_progress(self):
if self.status == RNS.Resource.COMPLETE and self.segment_index == self.total_segments:
return 1.0
elif self.initiator:
processed_parts = self.sent_parts
else:
processed_parts = self.received_count
progress = min(1.0, processed_parts / self.total_parts)
return progress
def get_transfer_size(self):
"""
:returns: The number of bytes needed to transfer the resource.
+13 -6
View File
@@ -29,6 +29,7 @@ if get_platform() == "android":
from .Interfaces import TCPInterface
from .Interfaces import UDPInterface
from .Interfaces import I2PInterface
from .Interfaces import RNodeMultiInterface
from .Interfaces.Android import RNodeInterface
from .Interfaces.Android import SerialInterface
from .Interfaces.Android import KISSInterface
@@ -991,7 +992,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:
@@ -1020,6 +1021,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
@@ -1045,10 +1051,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
@@ -1099,6 +1103,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)
@@ -1321,7 +1328,7 @@ class Reticulum:
if hasattr(interface, "r_battery_state"):
if interface.r_battery_state != 0x00:
ifstats["battery_state"] = interface.r_battery_state
ifstats["battery_state"] = interface.get_battery_state_string()
if hasattr(interface, "r_battery_percent"):
ifstats["battery_percent"] = interface.r_battery_percent
+11 -2
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
@@ -1738,7 +1738,16 @@ class Transport:
if link.link_id == packet.destination_hash:
if link.attached_interface == packet.receiving_interface:
packet.link = link
link.receive(packet)
if packet.context == RNS.Packet.CACHE_REQUEST:
cached_packet = Transport.get_cached_packet(packet.data)
if cached_packet != None:
cached_packet.unpack()
RNS.Packet(destination=link, data=cached_packet.data,
packet_type=cached_packet.packet_type, context=cached_packet.context).send()
Transport.jobs_locked = False
else:
link.receive(packet)
else:
# In the strange and rare case that an interface
# is partly malfunctioning, and a link-associated
+147 -55
View File
@@ -35,13 +35,18 @@ APP_NAME = "rncp"
allow_all = False
allow_fetch = False
fetch_jail = None
save_path = None
show_phy_rates = False
allowed_identity_hashes = []
REQ_FETCH_NOT_ALLOWED = 0xF0
es = " "
erase_str = "\33[2K\r"
def listen(configdir, verbosity = 0, quietness = 0, allowed = [], display_identity = False,
limit = None, disable_auth = None, fetch_allowed = False, jail = None, announce = False):
global allow_all, allow_fetch, allowed_identity_hashes, fetch_jail
limit = None, disable_auth = None, fetch_allowed = False, jail = None, save = None, announce = False):
global allow_all, allow_fetch, allowed_identity_hashes, fetch_jail, save_path
from tempfile import TemporaryFile
allow_fetch = fetch_allowed
@@ -56,6 +61,20 @@ def listen(configdir, verbosity = 0, quietness = 0, allowed = [], display_identi
fetch_jail = os.path.abspath(os.path.expanduser(jail))
RNS.log("Restricting fetch requests to paths under \""+fetch_jail+"\"", RNS.LOG_VERBOSE)
if save != None:
sp = os.path.abspath(os.path.expanduser(save))
if os.path.isdir(sp):
if os.access(sp, os.W_OK):
save_path = sp
else:
RNS.log("Output directory not writable", RNS.LOG_ERROR)
exit(4)
else:
RNS.log("Output directory not found", RNS.LOG_ERROR)
exit(3)
RNS.log("Saving received files in \""+save_path+"\"", RNS.LOG_VERBOSE)
identity_path = RNS.Reticulum.identitypath+"/"+APP_NAME
if os.path.isfile(identity_path):
identity = RNS.Identity.from_file(identity_path)
@@ -130,10 +149,15 @@ def listen(configdir, verbosity = 0, quietness = 0, allowed = [], display_identi
if not allow_fetch:
return REQ_FETCH_NOT_ALLOWED
file_path = os.path.abspath(os.path.expanduser(data))
if fetch_jail:
if not file_path.startswith(jail):
if data.startswith(fetch_jail+"/"):
data = data.replace(fetch_jail+"/", "")
file_path = os.path.abspath(os.path.expanduser(f"{fetch_jail}/{data}"))
if not file_path.startswith(fetch_jail+"/"):
RNS.log(f"Disallowing fetch request for {file_path} outside of fetch jail {fetch_jail}", RNS.LOG_WARNING)
return REQ_FETCH_NOT_ALLOWED
else:
file_path = os.path.abspath(os.path.expanduser(f"{data}"))
target_link = None
for link in RNS.Transport.active_links:
@@ -168,7 +192,13 @@ def listen(configdir, verbosity = 0, quietness = 0, allowed = [], display_identi
destination.set_link_established_callback(client_link_established)
destination.register_request_handler("fetch_file", response_generator=fetch_request, allow=RNS.Destination.ALLOW_LIST, allowed_list=allowed_identity_hashes)
if allow_fetch:
if allow_all:
RNS.log("Allowing unauthenticated fetch requests", RNS.LOG_WARNING)
destination.register_request_handler("fetch_file", response_generator=fetch_request, allow=RNS.Destination.ALLOW_ALL)
else:
destination.register_request_handler("fetch_file", response_generator=fetch_request, allow=RNS.Destination.ALLOW_LIST, allowed_list=allowed_identity_hashes)
print("rncp listening on "+RNS.prettyhexrep(destination.hash))
if announce >= 0:
@@ -227,6 +257,7 @@ def receive_resource_started(resource):
print("Starting resource transfer "+RNS.prettyhexrep(resource.hash)+id_str)
def receive_resource_concluded(resource):
global save_path
if resource.status == RNS.Resource.COMPLETE:
print(str(resource)+" completed")
@@ -235,12 +266,20 @@ def receive_resource_concluded(resource):
filename = resource.data.read(filename_len).decode("utf-8")
counter = 0
saved_filename = filename
while os.path.isfile(saved_filename):
if save_path:
saved_filename = os.path.abspath(os.path.expanduser(save_path+"/"+filename))
if not saved_filename.startswith(save_path+"/"):
RNS.log(f"Invalid save path {saved_filename}, ignoring", RNS.LOG_ERROR)
return
else:
saved_filename = filename
full_save_path = saved_filename
while os.path.isfile(full_save_path):
counter += 1
saved_filename = filename+"."+str(counter)
full_save_path = saved_filename+"."+str(counter)
file = open(saved_filename, "wb")
file = open(full_save_path, "wb")
file.write(resource.data.read())
file.close()
@@ -254,33 +293,57 @@ resource_done = False
current_resource = None
stats = []
speed = 0.0
phy_speed = 0.0
def sender_progress(resource):
stats_max = 32
global current_resource, stats, speed, resource_done
global current_resource, stats, speed, phy_speed, resource_done
current_resource = resource
now = time.time()
got = current_resource.get_progress()*current_resource.total_size
entry = [now, got]
got = current_resource.get_progress()*current_resource.get_data_size()
phy_got = current_resource.get_segment_progress()*current_resource.get_transfer_size()
entry = [now, got, phy_got]
stats.append(entry)
while len(stats) > stats_max:
stats.pop(0)
span = now - stats[0][0]
if span == 0:
speed = 0
phy_speed = 0
else:
diff = got - stats[0][1]
speed = diff/span
phy_diff = phy_got - stats[0][2]
if phy_diff > 0:
phy_speed = phy_diff/span
if resource.status < RNS.Resource.COMPLETE:
resource_done = False
else:
resource_done = True
link = None
def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = None, timeout = RNS.Transport.PATH_REQUEST_TIMEOUT, silent=False):
global current_resource, resource_done, link, speed
def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = None, timeout = RNS.Transport.PATH_REQUEST_TIMEOUT, silent=False, phy_rates=False, save=None):
global current_resource, resource_done, link, speed, show_phy_rates, save_path
targetloglevel = 3+verbosity-quietness
show_phy_rates = phy_rates
if save:
sp = os.path.abspath(os.path.expanduser(save))
if os.path.isdir(sp):
if os.access(sp, os.W_OK):
save_path = sp
else:
RNS.log("Output directory not writable", RNS.LOG_ERROR)
exit(4)
else:
RNS.log("Output directory not found", RNS.LOG_ERROR)
exit(3)
try:
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
@@ -315,7 +378,7 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
if silent:
print("Path to "+RNS.prettyhexrep(destination_hash)+" requested")
else:
print("Path to "+RNS.prettyhexrep(destination_hash)+" requested ", end=" ")
print("Path to "+RNS.prettyhexrep(destination_hash)+" requested ", end=es)
sys.stdout.flush()
i = 0
@@ -332,13 +395,13 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
if silent:
print("Path not found")
else:
print("\r \rPath not found")
print(f"{erase_str}Path not found")
exit(1)
else:
if silent:
print("Establishing link with "+RNS.prettyhexrep(destination_hash))
else:
print("\r \rEstablishing link with "+RNS.prettyhexrep(destination_hash)+" ", end=" ")
print(f"{erase_str}Establishing link with "+RNS.prettyhexrep(destination_hash)+" ", end=es)
listener_identity = RNS.Identity.recall(destination_hash)
listener_destination = RNS.Destination(
@@ -361,13 +424,13 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
if silent:
print("Could not establish link with "+RNS.prettyhexrep(destination_hash))
else:
print("\r \rCould not establish link with "+RNS.prettyhexrep(destination_hash))
print(f"{erase_str}Could not establish link with "+RNS.prettyhexrep(destination_hash))
exit(1)
else:
if silent:
print("Requesting file from remote...")
else:
print("\r \rRequesting file from remote ", end=" ")
print(f"{erase_str}Requesting file from remote ", end=es)
link.identify(identity)
@@ -402,18 +465,25 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
def fetch_resource_concluded(resource):
nonlocal resource_resolved, resource_status
global save_path
if resource.status == RNS.Resource.COMPLETE:
if resource.total_size > 4:
filename_len = int.from_bytes(resource.data.read(2), "big")
filename = resource.data.read(filename_len).decode("utf-8")
counter = 0
saved_filename = filename
while os.path.isfile(saved_filename):
if save_path:
saved_filename = os.path.abspath(os.path.expanduser(save_path+"/"+filename))
else:
saved_filename = filename
full_save_path = saved_filename
while os.path.isfile(full_save_path):
counter += 1
saved_filename = filename+"."+str(counter)
file = open(saved_filename, "wb")
full_save_path = saved_filename+"."+str(counter)
file = open(full_save_path, "wb")
file.write(resource.data.read())
file.close()
resource_status = "completed"
@@ -442,31 +512,31 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
i = (i+1)%len(syms)
if request_status == "fetch_not_allowed":
if not silent: print("\r \r", end="")
if not silent: print(f"{erase_str}", end="")
print("Fetch request failed, fetching the file "+str(file)+" was not allowed by the remote")
link.teardown()
time.sleep(0.15)
exit(0)
elif request_status == "not_found":
if not silent: print("\r \r", end="")
if not silent: print(f"{erase_str}", end="")
print("Fetch request failed, the file "+str(file)+" was not found on the remote")
link.teardown()
time.sleep(0.15)
exit(0)
elif request_status == "remote_error":
if not silent: print("\r \r", end="")
if not silent: print(f"{erase_str}", end="")
print("Fetch request failed due to an error on the remote system")
link.teardown()
time.sleep(0.15)
exit(0)
elif request_status == "unknown":
if not silent: print("\r \r", end="")
if not silent: print(f"{erase_str}", end="")
print("Fetch request failed due to an unknown error (probably not authorised)")
link.teardown()
time.sleep(0.15)
exit(0)
elif request_status == "found":
if not silent: print("\r \r", end="")
if not silent: print(f"{erase_str}", end="")
while not resource_resolved:
if not silent:
@@ -474,13 +544,21 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
if current_resource:
prg = current_resource.get_progress()
percent = round(prg * 100.0, 1)
stat_str = str(percent)+"% - " + size_str(int(prg*current_resource.total_size)) + " of " + size_str(current_resource.total_size) + " - " +size_str(speed, "b")+"ps"
if prg != 1.0:
print("\r \rTransferring file "+syms[i]+" "+stat_str, end=" ")
if show_phy_rates:
pss = size_str(phy_speed, "b")
phy_str = f" ({pss}ps at physical layer)"
else:
print("\r \rTransfer complete "+stat_str, end=" ")
phy_str = ""
ps = size_str(int(prg*current_resource.total_size))
ts = size_str(current_resource.total_size)
ss = size_str(speed, "b")
stat_str = f"{percent}% - {ps} of {ts} - {ss}ps{phy_str}"
if prg != 1.0:
print(f"{erase_str}Transferring file {syms[i]} {stat_str}", end=es)
else:
print(f"{erase_str}Transfer complete {stat_str}", end=es)
else:
print("\r \rWaiting for transfer to start "+syms[i]+" ", end=" ")
print(f"{erase_str}Waiting for transfer to start {syms[i]} ", end=es)
sys.stdout.flush()
i = (i+1)%len(syms)
@@ -488,13 +566,12 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
if silent:
print("The transfer failed")
else:
print("\r \rThe transfer failed")
print(f"{erase_str}The transfer failed")
exit(1)
else:
if silent:
print(str(file)+" fetched from "+RNS.prettyhexrep(destination_hash))
else:
#print("\r \r"+str(file)+" fetched from "+RNS.prettyhexrep(destination_hash))
print("\n"+str(file)+" fetched from "+RNS.prettyhexrep(destination_hash))
link.teardown()
time.sleep(0.15)
@@ -504,10 +581,11 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
exit(0)
def send(configdir, verbosity = 0, quietness = 0, destination = None, file = None, timeout = RNS.Transport.PATH_REQUEST_TIMEOUT, silent=False):
global current_resource, resource_done, link, speed
def send(configdir, verbosity = 0, quietness = 0, destination = None, file = None, timeout = RNS.Transport.PATH_REQUEST_TIMEOUT, silent=False, phy_rates=False):
global current_resource, resource_done, link, speed, show_phy_rates
from tempfile import TemporaryFile
targetloglevel = 3+verbosity-quietness
show_phy_rates = phy_rates
try:
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
@@ -536,14 +614,14 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
print("Filename exceeds max size, cannot send")
exit(1)
else:
print("Preparing file...", end=" ")
print("Preparing file...", end=es)
temp_file.write(filename_len.to_bytes(2, "big"))
temp_file.write(filename_bytes)
temp_file.write(real_file.read())
temp_file.seek(0)
print("\r \r", end="")
print(f"{erase_str}", end="")
reticulum = RNS.Reticulum(configdir=configdir, loglevel=targetloglevel)
@@ -566,7 +644,7 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if silent:
print("Path to "+RNS.prettyhexrep(destination_hash)+" requested")
else:
print("Path to "+RNS.prettyhexrep(destination_hash)+" requested ", end=" ")
print("Path to "+RNS.prettyhexrep(destination_hash)+" requested ", end=es)
sys.stdout.flush()
i = 0
@@ -583,13 +661,13 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if silent:
print("Path not found")
else:
print("\r \rPath not found")
print(f"{erase_str}Path not found")
exit(1)
else:
if silent:
print("Establishing link with "+RNS.prettyhexrep(destination_hash))
else:
print("\r \rEstablishing link with "+RNS.prettyhexrep(destination_hash)+" ", end=" ")
print(f"{erase_str}Establishing link with "+RNS.prettyhexrep(destination_hash)+" ", end=es)
receiver_identity = RNS.Identity.recall(destination_hash)
receiver_destination = RNS.Destination(
@@ -612,19 +690,19 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if silent:
print("Link establishment with "+RNS.prettyhexrep(destination_hash)+" timed out")
else:
print("\r \rLink establishment with "+RNS.prettyhexrep(destination_hash)+" timed out")
print(f"{erase_str}Link establishment with "+RNS.prettyhexrep(destination_hash)+" timed out")
exit(1)
elif not RNS.Transport.has_path(destination_hash):
if silent:
print("No path found to "+RNS.prettyhexrep(destination_hash))
else:
print("\r \rNo path found to "+RNS.prettyhexrep(destination_hash))
print(f"{erase_str}No path found to "+RNS.prettyhexrep(destination_hash))
exit(1)
else:
if silent:
print("Advertising file resource...")
else:
print("\r \rAdvertising file resource ", end=" ")
print(f"{erase_str}Advertising file resource ", end=es)
link.identify(identity)
resource = RNS.Resource(temp_file, link, callback = sender_progress, progress_callback = sender_progress)
@@ -642,23 +720,32 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if silent:
print("File was not accepted by "+RNS.prettyhexrep(destination_hash))
else:
print("\r \rFile was not accepted by "+RNS.prettyhexrep(destination_hash))
print(f"{erase_str}File was not accepted by "+RNS.prettyhexrep(destination_hash))
exit(1)
else:
if silent:
print("Transferring file...")
else:
print("\r \rTransferring file ", end=" ")
print(f"{erase_str}Transferring file ", end=es)
def progress_update(i, done=False):
time.sleep(0.1)
prg = current_resource.get_progress()
percent = round(prg * 100.0, 1)
stat_str = str(percent)+"% - " + size_str(int(prg*current_resource.total_size)) + " of " + size_str(current_resource.total_size) + " - " +size_str(speed, "b")+"ps"
if not done:
print("\r \rTransferring file "+syms[i]+" "+stat_str, end=" ")
if show_phy_rates:
pss = size_str(phy_speed, "b")
phy_str = f" ({pss}ps at physical layer)"
else:
print("\r \rTransfer complete "+stat_str, end=" ")
phy_str = ""
es = " "
cs = size_str(int(prg*current_resource.total_size))
ts = size_str(current_resource.total_size)
ss = size_str(speed, "b")
stat_str = f"{percent}% - {cs} of {ts} - {ss}ps{phy_str}"
if not done:
print(f"{erase_str}Transferring file "+syms[i]+" "+stat_str, end=es)
else:
print(f"{erase_str}Transfer complete "+stat_str, end=es)
sys.stdout.flush()
i = (i+1)%len(syms)
return i
@@ -674,13 +761,12 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if silent:
print("The transfer failed")
else:
print("\r \rThe transfer failed")
print(f"{erase_str}The transfer failed")
exit(1)
else:
if silent:
print(str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
else:
# print("\r \r"+str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
print("\n"+str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
link.teardown()
time.sleep(0.25)
@@ -701,11 +787,13 @@ def main():
parser.add_argument("-F", '--allow-fetch', action='store_true', default=False, help="allow authenticated clients to fetch files")
parser.add_argument("-f", '--fetch', action='store_true', default=False, help="fetch file from remote listener instead of sending")
parser.add_argument("-j", "--jail", metavar="path", action="store", default=None, help="restrict fetch requests to specified path", type=str)
parser.add_argument("-s", "--save", metavar="path", action="store", default=None, help="save received files in specified path", type=str)
parser.add_argument("-b", action='store', metavar="seconds", default=-1, help="announce interval, 0 to only announce at startup", type=int)
parser.add_argument('-a', metavar="allowed_hash", dest="allowed", action='append', help="allow this identity", type=str)
parser.add_argument('-a', metavar="allowed_hash", dest="allowed", action='append', help="allow this identity (or add in ~/.rncp/allowed_identities)", type=str)
parser.add_argument('-n', '--no-auth', action='store_true', default=False, help="accept requests from anyone")
parser.add_argument('-p', '--print-identity', action='store_true', default=False, help="print identity and destination info and exit")
parser.add_argument("-w", action="store", metavar="seconds", type=float, help="sender timeout before giving up", default=RNS.Transport.PATH_REQUEST_TIMEOUT)
parser.add_argument('-P', '--phy-rates', action='store_true', default=False, help="display physical layer transfer rates")
# parser.add_argument("--limit", action="store", metavar="files", type=float, help="maximum number of files to accept", default=None)
parser.add_argument("--version", action="version", version="rncp {version}".format(version=__version__))
@@ -719,6 +807,7 @@ def main():
allowed = args.allowed,
fetch_allowed = args.allow_fetch,
jail = args.jail,
save = args.save,
display_identity=args.print_identity,
# limit=args.limit,
disable_auth=args.no_auth,
@@ -735,6 +824,8 @@ def main():
file = args.file,
timeout = args.w,
silent = args.silent,
phy_rates = args.phy_rates,
save = args.save,
)
else:
print("")
@@ -750,6 +841,7 @@ def main():
file = args.file,
timeout = args.w,
silent = args.silent,
phy_rates = args.phy_rates,
)
else:
+171 -16
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"
@@ -139,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
@@ -169,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
@@ -207,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
@@ -214,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",
@@ -249,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"],
@@ -263,16 +278,20 @@ models = {
0xBB: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v10.zip", "SX1276"],
0xC4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_heltec32v2.zip", "SX1278"],
0xC9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_heltec32v2.zip", "SX1276"],
0xC5: [470000000, 510000000, 21, "470 - 510 MHz", "rnode_firmware_heltec32v3.zip", "SX1262"],
0xCA: [863000000, 928000000, 21, "863 - 928 MHz", "rnode_firmware_heltec32v3.zip", "SX1262"],
0xC5: [420000000, 520000000, 21, "420 - 520 MHz", "rnode_firmware_heltec32v3.zip", "SX1262"],
0xCA: [850000000, 950000000, 21, "850 - 950 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"],
@@ -1175,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)
@@ -1640,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.")
@@ -1651,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
@@ -1688,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()
@@ -1758,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("---------------------------------------------------------------------------")
@@ -1774,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("---------------------------------------------------------------------------")
@@ -1908,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
@@ -1957,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")
@@ -2789,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,
+2 -1
View File
@@ -295,7 +295,8 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
if "battery_percent" in ifstat and ifstat["battery_percent"] != None:
try:
bpi = int(ifstat["battery_percent"])
print(" Battery : {bp}%".format(bp=bpi))
bss = ifstat["battery_state"]
print(f" Battery : {bpi}% ({bss})")
except:
pass
+1 -1
View File
@@ -28,8 +28,8 @@ import argparse
import shlex
import time
import sys
import tty
import os
#import tty
from RNS._version import __version__
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.8.1"
__version__ = "0.8.4"
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: 1447e58e81cf4037238271210a352494
config: ab3a817981de13f74ede3061942f75d2
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
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.8.1 beta',
VERSION: '0.8.4 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.8.1 beta documentation</title>
<title>Code Examples - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>Getting Started Fast - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>Communications Hardware - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="#"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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="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.8.1 beta documentation</title>
<title>Configuring Interfaces - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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="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.8.1 beta documentation</title>
<title>Building Networks - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>API Reference - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 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.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>Support Reticulum - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>Understanding Reticulum - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</title>
<title>What is Reticulum? - Reticulum Network Stack 0.8.4 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.8.1 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.8.4 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.8.1 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.8.4 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