Compare commits

...

91 Commits

Author SHA1 Message Date
Mark Qvist ace0d997d4 Updated changelog 2024-03-02 00:40:44 +01:00
Mark Qvist 798c252284 Updated manual 2024-03-02 00:40:35 +01:00
Mark Qvist 7da22c8580 Updated documentation build 2024-03-01 00:47:12 +01:00
Mark Qvist eefbb89cde Updated version 2024-03-01 00:05:40 +01:00
Mark Qvist 18f50ff1ae Limit amount of random blobs kept in memory and persisted to disk. Add check for non-existent announce in processing table. 2024-03-01 00:03:56 +01:00
Mark Qvist 05e97ac0db Fixed saving known destination when on-disk storage file has become corrupted 2024-02-29 23:23:41 +01:00
Mark Qvist c2c3a144d2 Added payload data inactivity metric to Link API 2024-02-29 23:05:16 +01:00
markqvist ea369015ee Update issue templates 2024-02-29 17:07:53 +01:00
markqvist 9745842862 Update issue templates 2024-02-29 17:05:46 +01:00
markqvist 246289c52d Create config.yml 2024-02-29 17:04:17 +01:00
markqvist ff71cb2f98 Update issue templates 2024-02-29 16:58:57 +01:00
Mark Qvist 5ca1ef1777 Revert EEPROM check logic 2024-02-29 16:18:39 +01:00
Mark Qvist 2b764b4af8 Allow EEPROM checksum mismatch on autoinstall. Fixes #432. 2024-02-29 15:50:45 +01:00
Mark Qvist a62843cd75 Updated readme 2024-02-16 17:54:31 +01:00
Mark Qvist 633435390d Added ability to flash T3 boards with TCXO 2024-02-16 17:32:01 +01:00
Mark Qvist 1e207ef972 Updated readme 2024-02-16 17:31:42 +01:00
Mark Qvist 35e9a0b38a Updated changelog 2024-02-14 16:58:51 +01:00
Mark Qvist 3d7f3825fb Updated manual 2024-02-14 16:54:29 +01:00
Mark Qvist 04b67a545d Updated version 2024-02-13 19:01:07 +01:00
Mark Qvist 61c2fbd0da Merge branch 'master' of github.com:markqvist/Reticulum 2024-02-13 19:00:00 +01:00
Mark Qvist 1aba4ec43a Added support for SX126x-based RNodes 2024-02-13 18:59:23 +01:00
markqvist 841a3daa26 Merge pull request #439 from jacobeva/master
Update min and max values to support SX1280
2024-02-09 22:30:32 +01:00
jacob.eva d98f03f245 Update min and max values to support SX1280 2024-02-09 21:17:58 +00:00
Mark Qvist 878e67f69d Fixed invalid RSSI offset reference. Fixes #433. 2024-01-18 23:01:54 +01:00
Mark Qvist e582a6d6d1 Updated changelog 2024-01-17 22:59:02 +01:00
Mark Qvist a948afb816 Updated manual 2024-01-17 22:56:24 +01:00
Mark Qvist 86a294388f Merge branch 'master' of github.com:markqvist/Reticulum 2024-01-17 22:52:48 +01:00
Mark Qvist 429a0b1bd3 Updated changelog 2024-01-17 22:52:01 +01:00
Mark Qvist ee8bb42633 Updated manual 2024-01-17 22:51:16 +01:00
Mark Qvist c659388a2c Updated manual 2024-01-17 22:36:17 +01:00
markqvist eaa8199988 Merge pull request #428 from jacobeva/master
Add NRF52 support
2024-01-17 01:33:07 +01:00
jacob.eva 4f890e7e8a Added NRF52 support 2024-01-16 21:30:31 +00:00
Mark Qvist a37e039424 Check input_file attribut 2024-01-14 18:57:23 +01:00
Mark Qvist 8e1e2a9c54 Added debug function 2024-01-14 18:56:20 +01:00
Mark Qvist e4f94c9d0b Updated docs 2024-01-14 18:55:44 +01:00
Mark Qvist b007530123 Adjusted resource timeout calculation 2024-01-14 01:06:43 +01:00
Mark Qvist 4066bba303 Merge branch 'master' of github.com:markqvist/Reticulum 2024-01-14 00:48:14 +01:00
Mark Qvist 8951517d01 Updated version 2024-01-14 00:47:45 +01:00
Mark Qvist ae1d962b9b Fixed large resource transfers failing under some conditions 2024-01-14 00:46:55 +01:00
Mark Qvist a2caa47334 Improved link tests 2024-01-14 00:12:30 +01:00
Mark Qvist 9f43da9105 Fixed rnprobe formatting issue 2024-01-13 16:37:48 +01:00
Mark Qvist 038c696db9 Fixed missing check on malformed advertisement packets 2024-01-13 16:36:11 +01:00
Mark Qvist 8fa6ec144c Updated readme 2024-01-03 12:05:30 +01:00
Mark Qvist a8ccff7c55 Updated contribution guidelines 2024-01-03 12:00:10 +01:00
markqvist a5783da407 Merge pull request #416 from jooray/patch-2
Fix typo
2023-12-31 12:24:48 +01:00
Juraj Bednar bec3cee425 Fix typo 2023-12-30 23:47:51 +01:00
Mark Qvist b15bd19de5 Added funding info 2023-12-30 22:00:46 +01:00
Mark Qvist 38390fd021 Updated license 2023-12-30 21:57:40 +01:00
Mark Qvist 40e0eee64f Updated license 2023-12-30 21:55:20 +01:00
Mark Qvist af4cbb1baf Added funding info 2023-12-30 21:53:50 +01:00
Mark Qvist d3f4192fe3 Added funding info 2023-12-30 21:52:41 +01:00
Mark Qvist 47ef62ac11 Updated contribution guidelines 2023-12-30 21:43:35 +01:00
Mark Qvist d15ddc7a49 Updated contribution guidelines 2023-12-30 17:34:51 +01:00
Mark Qvist d67c8eb1cd Fixed potential division by zero 2023-12-25 11:39:24 +01:00
Mark Qvist f4de5d5199 Updated changelog 2023-12-07 15:52:20 +01:00
Mark Qvist 34e42988ea Updated docs 2023-12-07 15:51:22 +01:00
Mark Qvist 81d5d41149 Updated changelog 2023-12-07 15:51:15 +01:00
Mark Qvist 6b3f3a37f0 Updated version 2023-12-06 00:07:06 +01:00
Mark Qvist 60a604f635 Carrier change flag on listener replace 2023-12-06 00:06:45 +01:00
Mark Qvist 55a2daf379 Updated docs 2023-12-02 02:14:49 +01:00
Mark Qvist 2dbde13321 Added identity import and export in hex, base32 and base64 formats 2023-12-02 02:10:22 +01:00
Mark Qvist 6620dcde6b Updated docs 2023-11-14 10:06:28 +01:00
Mark Qvist 60966d5bb1 Updated changelog 2023-11-14 10:06:19 +01:00
Mark Qvist ea22a53bf2 Updated docs 2023-11-13 23:38:46 +01:00
Mark Qvist 7b9526b4ed Updated version 2023-11-13 23:23:40 +01:00
Mark Qvist 676074187a Added timeout and wait options to rnprobe and improved output formatting 2023-11-13 23:22:58 +01:00
Mark Qvist 5dd2c31caf Generate receipts prior to raw transmit 2023-11-13 23:12:59 +01:00
Mark Qvist 2db400a1a0 Updated changelog 2023-11-13 23:11:29 +01:00
Mark Qvist b68dbaf15e Updated log levels 2023-11-08 15:23:29 +01:00
Mark Qvist 84febcdf95 Updated changelog 2023-11-06 11:28:22 +01:00
Mark Qvist c972ef90c8 Updated manual 2023-11-06 11:21:32 +01:00
Mark Qvist 19a74e3130 Updated changelog 2023-11-06 11:21:23 +01:00
Mark Qvist 5ba789f782 Updated single-packet timing 2023-11-06 11:10:38 +01:00
Mark Qvist 58b5501e17 Cleanup 2023-11-06 11:08:31 +01:00
Mark Qvist b584832b8f Fixed logging error messages when a local client connects while instance is starting up 2023-11-06 11:06:14 +01:00
Mark Qvist fc0cf17c4d Updated docs 2023-11-05 23:37:45 +01:00
Mark Qvist 001dd369ec Updated version 2023-11-05 23:37:38 +01:00
Mark Qvist 9ce2ea4a5c Updated link test 2023-11-05 23:36:19 +01:00
Mark Qvist eec8814c22 Updated version 2023-11-05 23:29:06 +01:00
Mark Qvist 7a6ed68482 Set socket options 2023-11-05 22:57:03 +01:00
Mark Qvist cd9e23f2de Updated manual 2023-11-04 23:19:08 +01:00
Mark Qvist ffa84de0bc Updated changelog 2023-11-04 23:18:59 +01:00
Mark Qvist 89d3cdba17 Updated docs 2023-11-04 18:13:26 +01:00
Mark Qvist 2ba5843f22 Updated version 2023-11-04 18:05:42 +01:00
Mark Qvist c4d0f08767 Improved resource transfers over unreliable links 2023-11-04 18:05:20 +01:00
Mark Qvist db1cdec2a2 Fixed premature request timeout 2023-11-04 17:59:27 +01:00
Mark Qvist 1eea1a6a22 Updated example 2023-11-04 17:56:20 +01:00
Mark Qvist 4a69ce5a98 Updated changelog 2023-11-02 21:44:48 +01:00
Mark Qvist 8d653cba9b Updated docs 2023-11-02 21:39:57 +01:00
Mark Qvist a6126a6bc5 Updated version 2023-11-02 21:37:16 +01:00
Mark Qvist 957c2b3bc1 Fixed invalid reference 2023-11-02 21:33:21 +01:00
44 changed files with 887 additions and 358 deletions
+11
View File
@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: ✨ Feature Request or Idea
url: https://github.com/markqvist/Reticulum/discussions/new?category=ideas
about: Propose and discuss features and ideas
- name: 💬 Questions, Help & Discussion
about: Ask anything, or get help
url: https://github.com/markqvist/Reticulum/discussions/new/choose
- name: 📖 Read the Reticulum Manual
url: https://markqvist.github.io/Reticulum/manual/
about: The complete documentation for Reticulum
+35
View File
@@ -0,0 +1,35 @@
---
name: "\U0001F41B Bug Report"
about: Report a reproducible bug
title: ''
labels: ''
assignees: ''
---
**Read the Contribution Guidelines**
Before creating a bug report on this issue tracker, you **must** read the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md). Issues that do not follow the contribution guidelines **will be deleted without comment**.
- The issue tracker is used by developers of this project. **Do not use it to ask general questions, or for support requests**.
- Ideas and feature requests can be made on the [Discussions](https://github.com/markqvist/Reticulum/discussions). **Only** feature requests accepted by maintainers and developers are tracked and included on the issue tracker. **Do not post feature requests here**.
- After reading the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md), delete this section from your bug report.
**Describe the Bug**
A clear and concise description of what the bug is.
**To Reproduce**
Describe in detail how to reproduce the bug.
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Logs & Screenshots**
Please include any relevant log output. If applicable, also add screenshots to help explain your problem.
**System Information**
- OS and version
- Python version
- Program version
**Additional context**
Add any other context about the problem here.
+121 -1
View File
@@ -1,3 +1,123 @@
### 2024-03-02: RNS β 0.7.2
This maintenance release improves memory consumption, fixes a few bugs, and adds ability to flash new boards with `rnodeconf`.
**Changes**
- Added ability to flash new boards with `rnodeconf`, including T3 boards with TCXOs
- Improved memory consumption on Transport Instances with many interfaces
- Fixed a bug that could cause the on-disk known destinations store to become corrupted
**Release Hashes**
```
3ce3ba80d5ae8d19c6b55bd51f44bd4beccbcea31554cb1f0d65428e4587b3d6 rns-0.7.2-py3-none-any.whl
83f914aaba2a8929a8cee95830a847e190197232a0cca4e7b906b15c6bbf8296 rnspure-0.7.2-py3-none-any.whl
```
### 2024-02-14: RNS β 0.7.1
This release adds support for RNodes based on SX1262, SX1268 and SX1280 modems, and fixes a number of bugs. Thanks to @jacobeva, who contributed to this release!
**Changes**
- Added support for SX1262, SX1268 and SX1280 based RNodes
- Updated `rnodeconf` to allow flashing T-Beam devices with SX126x chips
- Fixed an invalid RSSI offset reference
**Release Hashes**
```
8ecfbb42b6a699fd4ac5374ab5640e4bb164e80bb9ab4401ea82da132e497877 rns-0.7.1-py3-none-any.whl
e0ab487305ba1aee2d16044640e7eb72d332bbf51aeb0b8bf984d037a64cb493 rnspure-0.7.1-py3-none-any.whl
```
### 2024-01-17: RNS β 0.7.0
This maintenance release fixes a number of bugs. Thanks to @jooray and @jacobeva, who contributed to this release!
**Changes**
- Fixed large resource transfers failing under some conditions
- Fixed a potential division by zero
- Fixed a missing check on malformed advertisement packets
- Fixed a formatting issue in `rnprobe`
- Improved resource timeout calculations
**Release Hashes**
```
0dc2abe5373b9afadfba7ec05bf7ddeff659c004aa339a94001ebed5b46f5b47 rns-0.7.0-py3-none-any.whl
97f6e65a20b53bbdccd54b4d2bdaa36dc1712e144a55f40800c63fe7113819a5 rnspure-0.7.0-py3-none-any.whl
```
### 2023-12-07: RNS β 0.6.9
This release adds a few convenience functions to the `rnid` utility, and improves roaming support on Android.
**Changes**
- Added identity import and export in hex, base32 and base64 formats to the `rnid` utility.
- Added better carrier change detection for AutoInterface on Android.
**Release Hashes**
```
258daf22cb6e72c6cd04fe94447daedf51dfd968eb2f3370eab9c71ad0898dd0 rns-0.6.9-py3-none-any.whl
3644b64af5b4efd3969172bf0cf95ae1afba6c8ea99ce47d8e49e31a832bbaf8 rnspure-0.6.9-py3-none-any.whl
```
### 2023-11-14: RNS β 0.6.8
This maintenance release fixes a single bug.
**Bugfixes**
- Fixed packet receipts not being initialised in time for arriving proofs on fast interfaces
**Release Hashes**
```
3ffb01f3f45e35105ea30e60e5e493ba50528df38b4ea62672c9e1c093073b1c rns-0.6.8-py3-none-any.whl
de372814082ef7db59f4b2745b1f22b2ef9d97815190ec16c0596ba20406e0fb rnspure-0.6.8-py3-none-any.whl
```
### 2023-11-06: RNS β 0.6.7
This maintenance release improves tranport performance and fixes a logging bug.
**Changes**
- Improved local and remote transport performance by approximately 6x on faster links
- Significantly decreased latency over faster links
**Bugfixes**
- Fixed logging an error message when local clients connect while shared instance is still starting up
**Release Hashes**
```
c37dd1f59e037841f69ec518deecdae6719f978947de2473f04e7d95247805ac rns-0.6.7-py3-none-any.whl
1e2dcb44ec7271a4d26180db138fc54dce6d0d3cf3f816432d4d6a4b1cf83868 rnspure-0.6.7-py3-none-any.whl
```
### 2023-11-04: RNS β 0.6.6
This maintenance release improves transfers over unreliable links and fixes a bug in requests.
**Changes**
- Improved reliability of resource transfers over very slow and unreliable links
**Bugfixes**
- Fixed a bug that could cause requests to timeout prematurely
**Release Hashes**
```
b1127745750a43cd7389212d31aa09ccc735ab2d69e3b80bd28874f10082c322 rns-0.6.6-py3-none-any.whl
bf5ba5da4f37b93c14817367952cda63787ec88bbe601e41c13fcbb3fc22b6b6 rnspure-0.6.6-py3-none-any.whl
```
### 2023-11-02: RNS β 0.6.5
This release fixes a bug in path rediscovery for shared instance clients.
**Bugfixes**
- Fixed a bug in path rediscovery for shared instance clients
**Release Hashes**
```
5d54a5cfebe907c759351357a8f7d771670c895ff57f1325bf7fec42bcb46ba3 rns-0.6.5-py3-none-any.whl
accd2855e18ff06455b9454957388089e293073ec7093c64dee0dc7aa46ecb46 rnspure-0.6.5-py3-none-any.whl
```
### 2023-11-02: RNS β 0.6.4 ### 2023-11-02: RNS β 0.6.4
This release fixes a number of bugs that had crept in while adding the new ultra low bandwidth link timing and faster path rediscovery mechanisms. This release fixes a number of bugs that had crept in while adding the new ultra low bandwidth link timing and faster path rediscovery mechanisms.
@@ -990,4 +1110,4 @@ This was the first publicly available pre-release alpha of Reticulum.
### 2016-05-29: Inintial Repository Commit ### 2016-05-29: Inintial Repository Commit
The first commit to the Reticulum reference implementation was 9a9630cfd29e11ace3f12716ddb4dff0e5419b4b, which occurred on Sunday, the 22nd of May 2016. The first commit to the Reticulum reference implementation was 9a9630cfd29e11ace3f12716ddb4dff0e5419b4b, which occurred on Sunday, the 29th of May 2016.
+14 -6
View File
@@ -2,21 +2,29 @@
Welcome, and thank you for your interest in contributing to Reticulum! Welcome, and thank you for your interest in contributing to Reticulum!
Apart from writing code, there are many ways in which you can contribute. Before getting started, please read these guidelines. Apart from writing code, there are many ways in which you can contribute. Before interacting with this community, read these short and simple guidelines.
## Expected Conduct
First and foremost, there is one simple requirement for taking part in this community: While we primarily interact virtually, your actions matter and have real consequences. Therefore: **Act like a responsible, civilized person** - also in the face of disputes and heated disagreements. Speak your mind here, discussions are welcome. Just do so in the spirit of being face-to-face with everyone else. Thank you.
## Asking Questions ## Asking Questions
If you want to ask a question, do not open an issue. If you want to ask a question, **do not open an issue**. The issue tracker is used by people *working on Reticulum* to track bugs, issues and improvements.
Instead, ask away on the [discussions](https://github.com/markqvist/Reticulum/discussions) or on the [Reticulum Matrix channel](https://unsigned.io/contact.html#reticulum:matrix.org) at `#reticulum:matrix.org` Instead, ask away on the [discussions](https://github.com/markqvist/Reticulum/discussions) or on the [Reticulum Matrix channel](https://matrix.to/#/#reticulum:matrix.org) at `#reticulum:matrix.org`
## Providing Feedback ## Providing Feedback & Ideas
Likewise, feedback, ideas and feature requests are a very welcome way to contribute, and should also be posted on the [discussions](https://github.com/markqvist/Reticulum/discussions), or on the [Reticulum Matrix channel](https://unsigned.io/contact.html#reticulum:matrix.org) at `#reticulum:matrix.org` Likewise, feedback, ideas and feature requests are a very welcome way to contribute, and should also be posted on the [discussions](https://github.com/markqvist/Reticulum/discussions), or on the [Reticulum Matrix channel](https://matrix.to/#/#reticulum:matrix.org) at `#reticulum:matrix.org`.
Please do not post feature requests or general ideas on the issue tracker, or in direct messages to the primary developers. You are much more likely to get a response and start a constructive discussion by posting your ideas in the public channels created for these purposes.
## Reporting Issues ## Reporting Issues
If you have found a bug or issue in Reticulum, please report it on the [issue tracker](https://github.com/markqvist/Reticulum/issues). If you have found a bug or issue in this project, please report it using the [issue tracker](https://github.com/markqvist/Reticulum/issues). If at all possible, be sure to include details on how to reproduce the bug.
Anything submitted to the issue tracker that does not follow these guidelines will be closed and removed without comments or explanation.
## Writing Code ## Writing Code
+1 -2
View File
@@ -449,8 +449,7 @@ def link_established(link):
# And set up a small job to check for # And set up a small job to check for
# a potential timeout in receiving the # a potential timeout in receiving the
# file list # file list
thread = threading.Thread(target=filelist_timeout_job) thread = threading.Thread(target=filelist_timeout_job, daemon=True)
thread.setDaemon(True)
thread.start() thread.start()
# This job just sleeps for the specified # This job just sleeps for the specified
+2
View File
@@ -0,0 +1,2 @@
ko_fi: markqvist
custom: "https://unsigned.io/donate"
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License, unless otherwise noted MIT License, unless otherwise noted
Copyright (c) 2016-2022 Mark Qvist / unsigned.io Copyright (c) 2016-2023 Mark Qvist / unsigned.io
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+4 -4
View File
@@ -192,7 +192,7 @@ provide a dynamic performance envelope from 250 bits per second, to 1 gigabit
per second on normal hardware. per second on normal hardware.
Currently, the usable performance envelope is approximately 150 bits per second Currently, the usable performance envelope is approximately 150 bits per second
to 20 megabits per second, with physical mediums faster than that not being to 40 megabits per second, with physical mediums faster than that not being
saturated. Performance beyond the current level is intended for future saturated. Performance beyond the current level is intended for future
upgrades, but not highly prioritised at this point in time. upgrades, but not highly prioritised at this point in time.
@@ -273,16 +273,16 @@ The testnet also contains a number of [Nomad Network](https://github.com/markqvi
You can help support the continued development of open, free and private communications systems by donating via one of the following channels: You can help support the continued development of open, free and private communications systems by donating via one of the following channels:
- Monero: - Monero:
``` ```
84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w 84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
``` ```
- Ethereum - Ethereum
``` ```
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a 0xFDabC71AC4c0C78C95aDDDe3B4FA19d6273c5E73
``` ```
- Bitcoin - Bitcoin
``` ```
3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq 35G9uWVzrpJJibzUwpNUQGQNFzLirhrYAH
``` ```
- Ko-Fi: https://ko-fi.com/markqvist - Ko-Fi: https://ko-fi.com/markqvist
+9 -4
View File
@@ -145,9 +145,12 @@ class Identity:
except: except:
pass pass
for destination_hash in storage_known_destinations: try:
if not destination_hash in Identity.known_destinations: for destination_hash in storage_known_destinations:
Identity.known_destinations[destination_hash] = storage_known_destinations[destination_hash] if not destination_hash in Identity.known_destinations:
Identity.known_destinations[destination_hash] = storage_known_destinations[destination_hash]
except Exception as e:
RNS.log("Skipped recombining known destinations from disk, since an error occurred: "+str(e), RNS.LOG_WARNING)
RNS.log("Saving "+str(len(Identity.known_destinations))+" known destinations to storage...", RNS.LOG_DEBUG) RNS.log("Saving "+str(len(Identity.known_destinations))+" known destinations to storage...", RNS.LOG_DEBUG)
file = open(RNS.Reticulum.storagepath+"/known_destinations","wb") file = open(RNS.Reticulum.storagepath+"/known_destinations","wb")
@@ -164,6 +167,7 @@ class Identity:
except Exception as e: except Exception as e:
RNS.log("Error while saving known destinations to disk, the contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error while saving known destinations to disk, the contained exception was: "+str(e), RNS.LOG_ERROR)
RNS.trace_exception(e)
Identity.saving_known_destinations = False Identity.saving_known_destinations = False
@@ -181,7 +185,8 @@ class Identity:
Identity.known_destinations[known_destination] = loaded_known_destinations[known_destination] Identity.known_destinations[known_destination] = loaded_known_destinations[known_destination]
RNS.log("Loaded "+str(len(Identity.known_destinations))+" known destination from storage", RNS.LOG_VERBOSE) RNS.log("Loaded "+str(len(Identity.known_destinations))+" known destination from storage", RNS.LOG_VERBOSE)
except:
except Exception as e:
RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR) RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR)
else: else:
RNS.log("Destinations file does not exist, no known destinations loaded", RNS.LOG_VERBOSE) RNS.log("Destinations file does not exist, no known destinations loaded", RNS.LOG_VERBOSE)
+3 -3
View File
@@ -115,7 +115,7 @@ class AndroidBluetoothManager():
if self.bt_enabled(): if self.bt_enabled():
return self.bt_adapter.getDefaultAdapter().getBondedDevices() return self.bt_adapter.getDefaultAdapter().getBondedDevices()
else: else:
RNS.log("Could not query paired devices, Bluetooth is disabled", RNS.LOG_DEBUG) RNS.log("Could not query paired devices, Bluetooth is disabled", RNS.LOG_EXTREME)
return [] return []
def get_potential_devices(self): def get_potential_devices(self):
@@ -167,8 +167,8 @@ class AndroidBluetoothManager():
raise IOError("The Bluetooth RFcomm socket could not be connected: "+str(e)) raise IOError("The Bluetooth RFcomm socket could not be connected: "+str(e))
except Exception as e: except Exception as e:
RNS.log("Could not create and connect Bluetooth RFcomm socket for "+str(device.getName())+" "+str(device.getAddress()), RNS.LOG_DEBUG) RNS.log("Could not create and connect Bluetooth RFcomm socket for "+str(device.getName())+" "+str(device.getAddress()), RNS.LOG_EXTREME)
RNS.log("The contained exception was: "+str(e), RNS.LOG_DEBUG) RNS.log("The contained exception was: "+str(e), RNS.LOG_EXTREME)
def close(self): def close(self):
if self.connected: if self.connected:
+2
View File
@@ -334,6 +334,8 @@ class AutoInterface(Interface):
thread.daemon = True thread.daemon = True
thread.start() thread.start()
self.carrier_changed = True
except Exception as e: except Exception as e:
RNS.log("Could not get device information while updating link-local addresses for "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Could not get device information while updating link-local addresses for "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
+1
View File
@@ -68,6 +68,7 @@ class Interface:
self.txb = 0 self.txb = 0
self.created = time.time() self.created = time.time()
self.online = False self.online = False
self.bitrate = 1e6
self.ingress_control = True self.ingress_control = True
self.ic_max_held_announces = Interface.MAX_HELD_ANNOUNCES self.ic_max_held_announces = Interface.MAX_HELD_ANNOUNCES
+4 -1
View File
@@ -78,6 +78,7 @@ class LocalClientInterface(Interface):
self.target_ip = None self.target_ip = None
self.target_port = None self.target_port = None
self.socket = connected_socket self.socket = connected_socket
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.is_connected_to_shared_instance = False self.is_connected_to_shared_instance = False
@@ -108,6 +109,7 @@ class LocalClientInterface(Interface):
def connect(self): def connect(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.socket.connect((self.target_ip, self.target_port)) self.socket.connect((self.target_ip, self.target_port))
self.online = True self.online = True
@@ -270,7 +272,8 @@ class LocalClientInterface(Interface):
RNS.Transport.local_client_interfaces.remove(self) RNS.Transport.local_client_interfaces.remove(self)
if hasattr(self, "parent_interface") and self.parent_interface != None: if hasattr(self, "parent_interface") and self.parent_interface != None:
self.parent_interface.clients -= 1 self.parent_interface.clients -= 1
RNS.Transport.owner._should_persist_data() if hasattr(RNS.Transport, "owner") and RNS.Transport.owner != None:
RNS.Transport.owner._should_persist_data()
if nowarning == False: if nowarning == False:
RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is being torn down. Restart Reticulum to attempt to open this interface again.", RNS.LOG_ERROR) RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is being torn down. Restart Reticulum to attempt to open this interface again.", RNS.LOG_ERROR)
+5 -5
View File
@@ -92,7 +92,7 @@ class RNodeInterface(Interface):
MAX_CHUNK = 32768 MAX_CHUNK = 32768
FREQ_MIN = 137000000 FREQ_MIN = 137000000
FREQ_MAX = 1020000000 FREQ_MAX = 3000000000
RSSI_OFFSET = 157 RSSI_OFFSET = 157
@@ -109,7 +109,7 @@ class RNodeInterface(Interface):
def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False, id_interval = None, id_callsign = None, st_alock = None, lt_alock = None): def __init__(self, owner, name, port, frequency = None, bandwidth = None, txpower = None, sf = None, cr = None, flow_control = False, id_interval = None, id_callsign = None, st_alock = None, lt_alock = None):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
raise SystemError("Invlaid interface type. The Android-specific RNode interface must be used on Android") raise SystemError("Invalid interface type. The Android-specific RNode interface must be used on Android")
import importlib import importlib
if importlib.util.find_spec('serial') != None: if importlib.util.find_spec('serial') != None:
@@ -190,15 +190,15 @@ class RNodeInterface(Interface):
RNS.log("Invalid frequency configured for "+str(self), RNS.LOG_ERROR) RNS.log("Invalid frequency configured for "+str(self), RNS.LOG_ERROR)
self.validcfg = False self.validcfg = False
if (self.txpower < 0 or self.txpower > 17): if (self.txpower < 0 or self.txpower > 22):
RNS.log("Invalid TX power configured for "+str(self), RNS.LOG_ERROR) RNS.log("Invalid TX power configured for "+str(self), RNS.LOG_ERROR)
self.validcfg = False self.validcfg = False
if (self.bandwidth < 7800 or self.bandwidth > 500000): if (self.bandwidth < 7800 or self.bandwidth > 1625000):
RNS.log("Invalid bandwidth configured for "+str(self), RNS.LOG_ERROR) RNS.log("Invalid bandwidth configured for "+str(self), RNS.LOG_ERROR)
self.validcfg = False self.validcfg = False
if (self.sf < 7 or self.sf > 12): if (self.sf < 5 or self.sf > 12):
RNS.log("Invalid spreading factor configured for "+str(self), RNS.LOG_ERROR) RNS.log("Invalid spreading factor configured for "+str(self), RNS.LOG_ERROR)
self.validcfg = False self.validcfg = False
+3
View File
@@ -116,6 +116,8 @@ class TCPClientInterface(Interface):
elif platform.system() == "Darwin": elif platform.system() == "Darwin":
self.set_timeouts_osx() self.set_timeouts_osx()
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
elif target_ip != None and target_port != None: elif target_ip != None and target_port != None:
self.receives = True self.receives = True
self.target_ip = target_ip self.target_ip = target_ip
@@ -200,6 +202,7 @@ class TCPClientInterface(Interface):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(TCPClientInterface.INITIAL_CONNECT_TIMEOUT) self.socket.settimeout(TCPClientInterface.INITIAL_CONNECT_TIMEOUT)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.socket.connect((self.target_ip, self.target_port)) self.socket.connect((self.target_ip, self.target_port))
self.socket.settimeout(None) self.socket.settimeout(None)
self.online = True self.online = True
+54 -45
View File
@@ -124,7 +124,7 @@ class Link:
link.last_inbound = time.time() link.last_inbound = time.time()
link.start_watchdog() link.start_watchdog()
RNS.log("Incoming link request "+str(link)+" accepted", RNS.LOG_VERBOSE) RNS.log("Incoming link request "+str(link)+" accepted", RNS.LOG_DEBUG)
return link return link
except Exception as e: except Exception as e:
@@ -133,7 +133,7 @@ class Link:
return None return None
else: else:
RNS.log("Invalid link request payload size, dropping request", RNS.LOG_VERBOSE) RNS.log("Invalid link request payload size, dropping request", RNS.LOG_DEBUG)
return None return None
@@ -150,6 +150,7 @@ class Link:
self.last_inbound = 0 self.last_inbound = 0
self.last_outbound = 0 self.last_outbound = 0
self.last_proof = 0 self.last_proof = 0
self.last_data = 0
self.tx = 0 self.tx = 0
self.rx = 0 self.rx = 0
self.txbytes = 0 self.txbytes = 0
@@ -352,7 +353,7 @@ class Link:
packed_request = umsgpack.packb(unpacked_request) packed_request = umsgpack.packb(unpacked_request)
if timeout == None: if timeout == None:
timeout = self.rtt * self.traffic_timeout_factor + RNS.Resource.RESPONSE_MAX_GRACE_TIME/4.0 timeout = self.rtt * self.traffic_timeout_factor + RNS.Resource.RESPONSE_MAX_GRACE_TIME*1.125
if len(packed_request) <= Link.MDU: if len(packed_request) <= Link.MDU:
request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST) request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST)
@@ -460,7 +461,7 @@ class Link:
def no_inbound_for(self): def no_inbound_for(self):
""" """
:returns: The time in seconds since last inbound packet on the link. :returns: The time in seconds since last inbound packet on the link. This includes keepalive packets.
""" """
activated_at = self.activated_at if self.activated_at != None else 0 activated_at = self.activated_at if self.activated_at != None else 0
last_inbound = max(self.last_inbound, activated_at) last_inbound = max(self.last_inbound, activated_at)
@@ -468,13 +469,19 @@ class Link:
def no_outbound_for(self): def no_outbound_for(self):
""" """
:returns: The time in seconds since last outbound packet on the link. :returns: The time in seconds since last outbound packet on the link. This includes keepalive packets.
""" """
return time.time() - self.last_outbound return time.time() - self.last_outbound
def no_data_for(self):
"""
:returns: The time in seconds since payload data traversed the link. This excludes keepalive packets.
"""
return time.time() - self.last_data
def inactive_for(self): def inactive_for(self):
""" """
:returns: The time in seconds since activity on the link. :returns: The time in seconds since activity on the link. This includes keepalive packets.
""" """
return min(self.no_inbound_for(), self.no_outbound_for()) return min(self.no_inbound_for(), self.no_outbound_for())
@@ -484,8 +491,10 @@ class Link:
""" """
return self.__remote_identity return self.__remote_identity
def had_outbound(self): def had_outbound(self, is_keepalive=False):
self.last_outbound = time.time() self.last_outbound = time.time()
if not is_keepalive:
self.last_data = self.last_outbound
def teardown(self): def teardown(self):
""" """
@@ -636,7 +645,7 @@ class Link:
def send_keepalive(self): def send_keepalive(self):
keepalive_packet = RNS.Packet(self, bytes([0xFF]), context=RNS.Packet.KEEPALIVE) keepalive_packet = RNS.Packet(self, bytes([0xFF]), context=RNS.Packet.KEEPALIVE)
keepalive_packet.send() keepalive_packet.send()
self.had_outbound() self.had_outbound(is_keepalive = True)
def handle_request(self, request_id, unpacked_request): def handle_request(self, request_id, unpacked_request):
if self.status == Link.ACTIVE: if self.status == Link.ACTIVE:
@@ -687,7 +696,9 @@ class Link:
remove = pending_request remove = pending_request
try: try:
pending_request.response_size = response_size pending_request.response_size = response_size
pending_request.response_transfer_size = response_transfer_size if pending_request.response_transfer_size == None:
pending_request.response_transfer_size = 0
pending_request.response_transfer_size += response_transfer_size
pending_request.response_received(response_data) pending_request.response_received(response_data)
except Exception as e: except Exception as e:
RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR)
@@ -740,6 +751,8 @@ class Link:
RNS.log("Link-associated packet received on unexpected interface! Someone might be trying to manipulate your communication!", RNS.LOG_ERROR) RNS.log("Link-associated packet received on unexpected interface! Someone might be trying to manipulate your communication!", RNS.LOG_ERROR)
else: else:
self.last_inbound = time.time() self.last_inbound = time.time()
if packet.context != RNS.Packet.KEEPALIVE:
self.last_data = self.last_inbound
self.rx += 1 self.rx += 1
self.rxbytes += len(packet.data) self.rxbytes += len(packet.data)
if self.status == Link.STALE: if self.status == Link.STALE:
@@ -834,10 +847,17 @@ class Link:
request_id = RNS.ResourceAdvertisement.read_request_id(packet) request_id = RNS.ResourceAdvertisement.read_request_id(packet)
for pending_request in self.pending_requests: for pending_request in self.pending_requests:
if pending_request.request_id == request_id: if pending_request.request_id == request_id:
RNS.Resource.accept(packet, callback=self.response_resource_concluded, progress_callback=pending_request.response_resource_progress, request_id = request_id) response_resource = RNS.Resource.accept(packet, callback=self.response_resource_concluded, progress_callback=pending_request.response_resource_progress, request_id = request_id)
pending_request.response_size = RNS.ResourceAdvertisement.read_size(packet) if response_resource != None:
pending_request.response_transfer_size = RNS.ResourceAdvertisement.read_transfer_size(packet) if pending_request.response_size == None:
pending_request.started_at = time.time() pending_request.response_size = RNS.ResourceAdvertisement.read_size(packet)
if pending_request.response_transfer_size == None:
pending_request.response_transfer_size = 0
pending_request.response_transfer_size += RNS.ResourceAdvertisement.read_transfer_size(packet)
if pending_request.started_at == None:
pending_request.started_at = time.time()
pending_request.response_resource_progress(response_resource)
elif self.resource_strategy == Link.ACCEPT_NONE: elif self.resource_strategy == Link.ACCEPT_NONE:
pass pass
elif self.resource_strategy == Link.ACCEPT_APP: elif self.resource_strategy == Link.ACCEPT_APP:
@@ -891,7 +911,7 @@ class Link:
if not self.initiator and packet.data == bytes([0xFF]): if not self.initiator and packet.data == bytes([0xFF]):
keepalive_packet = RNS.Packet(self, bytes([0xFE]), context=RNS.Packet.KEEPALIVE) keepalive_packet = RNS.Packet(self, bytes([0xFE]), context=RNS.Packet.KEEPALIVE)
keepalive_packet.send() keepalive_packet.send()
self.had_outbound() self.had_outbound(is_keepalive = True)
# TODO: find the most efficient way to allow multiple # TODO: find the most efficient way to allow multiple
@@ -907,20 +927,6 @@ class Link:
if not self._channel: if not self._channel:
RNS.log(f"Channel data received without open channel", RNS.LOG_DEBUG) RNS.log(f"Channel data received without open channel", RNS.LOG_DEBUG)
else: else:
# TODO: Remove packet loss simulator ######
# if not hasattr(self, "drop_counter"):
# self.drop_counter = 0
# self.drop_counter += 1
# if self.drop_counter%6 == 0:
# RNS.log("Dropping channel packet for testing", RNS.LOG_DEBUG)
# else:
# packet.prove()
# plaintext = self.decrypt(packet.data)
# if plaintext != None:
# self._channel._receive(plaintext)
############################################
packet.prove() packet.prove()
plaintext = self.decrypt(packet.data) plaintext = self.decrypt(packet.data)
if plaintext != None: if plaintext != None:
@@ -1144,7 +1150,8 @@ class RequestReceipt():
def request_resource_concluded(self, resource): def request_resource_concluded(self, resource):
if resource.status == RNS.Resource.COMPLETE: if resource.status == RNS.Resource.COMPLETE:
RNS.log("Request "+RNS.prettyhexrep(self.request_id)+" successfully sent as resource.", RNS.LOG_DEBUG) RNS.log("Request "+RNS.prettyhexrep(self.request_id)+" successfully sent as resource.", RNS.LOG_DEBUG)
self.started_at = time.time() if self.started_at == None:
self.started_at = time.time()
self.status = RequestReceipt.DELIVERED self.status = RequestReceipt.DELIVERED
self.__resource_response_timeout = time.time()+self.timeout self.__resource_response_timeout = time.time()+self.timeout
response_timeout_thread = threading.Thread(target=self.__response_timeout_job) response_timeout_thread = threading.Thread(target=self.__response_timeout_job)
@@ -1185,24 +1192,26 @@ class RequestReceipt():
def response_resource_progress(self, resource): def response_resource_progress(self, resource):
if not self.status == RequestReceipt.FAILED: if resource != None:
self.status = RequestReceipt.RECEIVING if not self.status == RequestReceipt.FAILED:
if self.packet_receipt != None: self.status = RequestReceipt.RECEIVING
self.packet_receipt.status = RNS.PacketReceipt.DELIVERED if self.packet_receipt != None:
self.packet_receipt.proved = True if self.packet_receipt.status != RNS.PacketReceipt.DELIVERED:
self.packet_receipt.concluded_at = time.time() self.packet_receipt.status = RNS.PacketReceipt.DELIVERED
if self.packet_receipt.callbacks.delivery != None: self.packet_receipt.proved = True
self.packet_receipt.callbacks.delivery(self.packet_receipt) self.packet_receipt.concluded_at = time.time()
if self.packet_receipt.callbacks.delivery != None:
self.packet_receipt.callbacks.delivery(self.packet_receipt)
self.progress = resource.get_progress() self.progress = resource.get_progress()
if self.callbacks.progress != None: if self.callbacks.progress != None:
try: try:
self.callbacks.progress(self) self.callbacks.progress(self)
except Exception as e: except Exception as e:
RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
else: else:
resource.cancel() resource.cancel()
def response_received(self, response): def response_received(self, response):
+118 -92
View File
@@ -25,7 +25,9 @@ import os
import bz2 import bz2
import math import math
import time import time
import tempfile
import threading import threading
from threading import Lock
from .vendor import umsgpack as umsgpack from .vendor import umsgpack as umsgpack
from time import sleep from time import sleep
@@ -47,7 +49,7 @@ class Resource:
WINDOW = 4 WINDOW = 4
# Absolute minimum window size during transfer # Absolute minimum window size during transfer
WINDOW_MIN = 1 WINDOW_MIN = 2
# The maximum window size for transfers on slow links # The maximum window size for transfers on slow links
WINDOW_MAX_SLOW = 10 WINDOW_MAX_SLOW = 10
@@ -103,9 +105,10 @@ class Resource:
PART_TIMEOUT_FACTOR = 4 PART_TIMEOUT_FACTOR = 4
PART_TIMEOUT_FACTOR_AFTER_RTT = 2 PART_TIMEOUT_FACTOR_AFTER_RTT = 2
MAX_RETRIES = 8 MAX_RETRIES = 16
MAX_ADV_RETRIES = 4 MAX_ADV_RETRIES = 4
SENDER_GRACE_TIME = 10 SENDER_GRACE_TIME = 10.0
PROCESSING_GRACE = 1.0
RETRY_GRACE_TIME = 0.25 RETRY_GRACE_TIME = 0.25
PER_RETRY_DELAY = 0.5 PER_RETRY_DELAY = 0.5
@@ -167,10 +170,8 @@ class Resource:
resource.hashmap = [None] * resource.total_parts resource.hashmap = [None] * resource.total_parts
resource.hashmap_height = 0 resource.hashmap_height = 0
resource.waiting_for_hmu = False resource.waiting_for_hmu = False
resource.receiving_part = False resource.receiving_part = False
resource.consecutive_completed_height = -1
resource.consecutive_completed_height = 0
if not resource.link.has_incoming_resource(resource): if not resource.link.has_incoming_resource(resource):
resource.link.register_incoming_resource(resource) resource.link.register_incoming_resource(resource)
@@ -204,9 +205,19 @@ class Resource:
resource_data = None resource_data = None
self.assembly_lock = False self.assembly_lock = False
if data != None:
if not hasattr(data, "read") and len(data) > Resource.MAX_EFFICIENT_SIZE:
original_data = data
data_size = len(original_data)
data = tempfile.TemporaryFile()
data.write(original_data)
del original_data
if hasattr(data, "read"): if hasattr(data, "read"):
data_size = os.stat(data.name).st_size if data_size == None:
self.total_size = data_size data_size = os.stat(data.name).st_size
self.total_size = data_size
self.grand_total_parts = math.ceil(data_size/Resource.SDU) self.grand_total_parts = math.ceil(data_size/Resource.SDU)
if data_size <= Resource.MAX_EFFICIENT_SIZE: if data_size <= Resource.MAX_EFFICIENT_SIZE:
@@ -279,7 +290,7 @@ class Resource:
self.uncompressed_data = data self.uncompressed_data = data
compression_began = time.time() compression_began = time.time()
if (auto_compress and len(self.uncompressed_data) < Resource.AUTO_COMPRESS_MAX_SIZE): if (auto_compress and len(self.uncompressed_data) <= Resource.AUTO_COMPRESS_MAX_SIZE):
RNS.log("Compressing resource data...", RNS.LOG_DEBUG) RNS.log("Compressing resource data...", RNS.LOG_DEBUG)
self.compressed_data = bz2.compress(self.uncompressed_data) self.compressed_data = bz2.compress(self.uncompressed_data)
RNS.log("Compression completed in "+str(round(time.time()-compression_began, 3))+" seconds", RNS.LOG_DEBUG) RNS.log("Compression completed in "+str(round(time.time()-compression_began, 3))+" seconds", RNS.LOG_DEBUG)
@@ -366,7 +377,8 @@ class Resource:
if advertise: if advertise:
self.advertise() self.advertise()
else: else:
pass self.receive_lock = Lock()
def hashmap_update_packet(self, plaintext): def hashmap_update_packet(self, plaintext):
if not self.status == Resource.FAILED: if not self.status == Resource.FAILED:
@@ -440,7 +452,7 @@ class Resource:
sleep_time = None sleep_time = None
if self.status == Resource.ADVERTISED: if self.status == Resource.ADVERTISED:
sleep_time = (self.adv_sent+self.timeout)-time.time() sleep_time = (self.adv_sent+self.timeout+Resource.PROCESSING_GRACE)-time.time()
if sleep_time < 0: if sleep_time < 0:
if self.retries_left <= 0: if self.retries_left <= 0:
RNS.log("Resource transfer timeout after sending advertisement", RNS.LOG_DEBUG) RNS.log("Resource transfer timeout after sending advertisement", RNS.LOG_DEBUG)
@@ -456,7 +468,7 @@ class Resource:
self.adv_sent = self.last_activity self.adv_sent = self.last_activity
sleep_time = 0.001 sleep_time = 0.001
except Exception as e: except Exception as e:
RNS.log("Could not resend advertisement packet, cancelling resource", RNS.LOG_VERBOSE) RNS.log("Could not resend advertisement packet, cancelling resource. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
self.cancel() self.cancel()
@@ -612,10 +624,26 @@ class Resource:
self.callback(self) self.callback(self)
except Exception as e: except Exception as e:
RNS.log("Error while executing resource concluded callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error while executing resource concluded callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
finally:
try:
if hasattr(self, "input_file"):
if hasattr(self.input_file, "close") and callable(self.input_file.close):
self.input_file.close()
except Exception as e:
RNS.log("Error while closing resource input file: "+str(e), RNS.LOG_ERROR)
else: else:
# Otherwise we'll recursively create the # Otherwise we'll recursively create the
# next segment of the resource # next segment of the resource
Resource(self.input_file, self.link, callback = self.callback, segment_index = self.segment_index+1, original_hash=self.original_hash, progress_callback = self.__progress_callback) Resource(
self.input_file, self.link,
callback = self.callback,
segment_index = self.segment_index+1,
original_hash=self.original_hash,
progress_callback = self.__progress_callback,
request_id = self.request_id,
is_response = self.is_response,
)
else: else:
pass pass
else: else:
@@ -623,99 +651,99 @@ class Resource:
def receive_part(self, packet): def receive_part(self, packet):
while self.receiving_part: with self.receive_lock:
sleep(0.001)
self.receiving_part = True self.receiving_part = True
self.last_activity = time.time() self.last_activity = time.time()
self.retries_left = self.max_retries self.retries_left = self.max_retries
if self.req_resp == None: if self.req_resp == None:
self.req_resp = self.last_activity self.req_resp = self.last_activity
rtt = self.req_resp-self.req_sent rtt = self.req_resp-self.req_sent
self.part_timeout_factor = Resource.PART_TIMEOUT_FACTOR_AFTER_RTT self.part_timeout_factor = Resource.PART_TIMEOUT_FACTOR_AFTER_RTT
if self.rtt == None: if self.rtt == None:
self.rtt = self.link.rtt self.rtt = self.link.rtt
self.watchdog_job() self.watchdog_job()
elif rtt < self.rtt: elif rtt < self.rtt:
self.rtt = max(self.rtt - self.rtt*0.05, rtt) self.rtt = max(self.rtt - self.rtt*0.05, rtt)
elif rtt > self.rtt: elif rtt > self.rtt:
self.rtt = min(self.rtt + self.rtt*0.05, rtt) self.rtt = min(self.rtt + self.rtt*0.05, rtt)
if rtt > 0: if rtt > 0:
req_resp_cost = len(packet.raw)+self.req_sent_bytes req_resp_cost = len(packet.raw)+self.req_sent_bytes
self.req_resp_rtt_rate = req_resp_cost / rtt self.req_resp_rtt_rate = req_resp_cost / rtt
if self.req_resp_rtt_rate > Resource.RATE_FAST and self.fast_rate_rounds < Resource.FAST_RATE_THRESHOLD: if self.req_resp_rtt_rate > Resource.RATE_FAST and self.fast_rate_rounds < Resource.FAST_RATE_THRESHOLD:
self.fast_rate_rounds += 1 self.fast_rate_rounds += 1
if self.fast_rate_rounds == Resource.FAST_RATE_THRESHOLD: if self.fast_rate_rounds == Resource.FAST_RATE_THRESHOLD:
self.window_max = Resource.WINDOW_MAX_FAST self.window_max = Resource.WINDOW_MAX_FAST
if not self.status == Resource.FAILED: if not self.status == Resource.FAILED:
self.status = Resource.TRANSFERRING self.status = Resource.TRANSFERRING
part_data = packet.data part_data = packet.data
part_hash = self.get_map_hash(part_data) part_hash = self.get_map_hash(part_data)
i = self.consecutive_completed_height consecutive_index = self.consecutive_completed_height if self.consecutive_completed_height >= 0 else 0
for map_hash in self.hashmap[self.consecutive_completed_height:self.consecutive_completed_height+self.window]: i = consecutive_index
if map_hash == part_hash: for map_hash in self.hashmap[consecutive_index:consecutive_index+self.window]:
if self.parts[i] == None: if map_hash == part_hash:
if self.parts[i] == None:
# Insert data into parts list # Insert data into parts list
self.parts[i] = part_data self.parts[i] = part_data
self.rtt_rxd_bytes += len(part_data) self.rtt_rxd_bytes += len(part_data)
self.received_count += 1 self.received_count += 1
self.outstanding_parts -= 1 self.outstanding_parts -= 1
# Update consecutive completed pointer # Update consecutive completed pointer
if i == self.consecutive_completed_height + 1: if i == self.consecutive_completed_height + 1:
self.consecutive_completed_height = i self.consecutive_completed_height = i
cp = self.consecutive_completed_height + 1 cp = self.consecutive_completed_height + 1
while cp < len(self.parts) and self.parts[cp] != None: while cp < len(self.parts) and self.parts[cp] != None:
self.consecutive_completed_height = cp self.consecutive_completed_height = cp
cp += 1 cp += 1
if self.__progress_callback != None: if self.__progress_callback != None:
try: try:
self.__progress_callback(self) self.__progress_callback(self)
except Exception as e: except Exception as e:
RNS.log("Error while executing progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error while executing progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
i += 1 i += 1
self.receiving_part = False self.receiving_part = False
if self.received_count == self.total_parts and not self.assembly_lock: if self.received_count == self.total_parts and not self.assembly_lock:
self.assembly_lock = True self.assembly_lock = True
self.assemble() self.assemble()
elif self.outstanding_parts == 0: elif self.outstanding_parts == 0:
# TODO: Figure out if there is a mathematically # TODO: Figure out if there is a mathematically
# optimal way to adjust windows # optimal way to adjust windows
if self.window < self.window_max: if self.window < self.window_max:
self.window += 1 self.window += 1
if (self.window - self.window_min) > (self.window_flexibility-1): if (self.window - self.window_min) > (self.window_flexibility-1):
self.window_min += 1 self.window_min += 1
if self.req_sent != 0: if self.req_sent != 0:
rtt = time.time()-self.req_sent rtt = time.time()-self.req_sent
req_transferred = self.rtt_rxd_bytes - self.rtt_rxd_bytes_at_part_req req_transferred = self.rtt_rxd_bytes - self.rtt_rxd_bytes_at_part_req
if rtt != 0: if rtt != 0:
self.req_data_rtt_rate = req_transferred/rtt self.req_data_rtt_rate = req_transferred/rtt
self.rtt_rxd_bytes_at_part_req = self.rtt_rxd_bytes self.rtt_rxd_bytes_at_part_req = self.rtt_rxd_bytes
if self.req_data_rtt_rate > Resource.RATE_FAST and self.fast_rate_rounds < Resource.FAST_RATE_THRESHOLD: if self.req_data_rtt_rate > Resource.RATE_FAST and self.fast_rate_rounds < Resource.FAST_RATE_THRESHOLD:
self.fast_rate_rounds += 1 self.fast_rate_rounds += 1
if self.fast_rate_rounds == Resource.FAST_RATE_THRESHOLD: if self.fast_rate_rounds == Resource.FAST_RATE_THRESHOLD:
self.window_max = Resource.WINDOW_MAX_FAST self.window_max = Resource.WINDOW_MAX_FAST
self.request_next() self.request_next()
else: else:
self.receiving_part = False self.receiving_part = False
# Called on incoming resource to send a request for more data # Called on incoming resource to send a request for more data
def request_next(self): def request_next(self):
@@ -728,11 +756,11 @@ class Resource:
hashmap_exhausted = Resource.HASHMAP_IS_NOT_EXHAUSTED hashmap_exhausted = Resource.HASHMAP_IS_NOT_EXHAUSTED
requested_hashes = b"" requested_hashes = b""
offset = (1 if self.consecutive_completed_height > 0 else 0) i = 0; pn = self.consecutive_completed_height+1
i = 0; pn = self.consecutive_completed_height+offset
search_start = pn search_start = pn
search_size = self.window
for part in self.parts[search_start:search_start+self.window]: for part in self.parts[search_start:search_start+search_size]:
if part == None: if part == None:
part_hash = self.hashmap[pn] part_hash = self.hashmap[pn]
if part_hash != None: if part_hash != None:
@@ -752,7 +780,6 @@ class Resource:
hmu_part += last_map_hash hmu_part += last_map_hash
self.waiting_for_hmu = True self.waiting_for_hmu = True
requested_data = b""
request_data = hmu_part + self.hash + requested_hashes request_data = hmu_part + self.hash + requested_hashes
request_packet = RNS.Packet(self.link, request_data, context = RNS.Packet.RESOURCE_REQ) request_packet = RNS.Packet(self.link, request_data, context = RNS.Packet.RESOURCE_REQ)
@@ -908,8 +935,7 @@ class Resource:
else: else:
self.progress_total_parts = float(self.total_parts) self.progress_total_parts = float(self.total_parts)
progress = min(1.0, self.processed_parts / self.progress_total_parts)
progress = self.processed_parts / self.progress_total_parts
return progress return progress
def get_transfer_size(self): def get_transfer_size(self):
+35 -27
View File
@@ -77,6 +77,8 @@ class Transport:
DESTINATION_TIMEOUT = 60*60*24*7 # Destination table entries are removed if unused for one week DESTINATION_TIMEOUT = 60*60*24*7 # Destination table entries are removed if unused for one week
MAX_RECEIPTS = 1024 # Maximum number of receipts to keep track of MAX_RECEIPTS = 1024 # Maximum number of receipts to keep track of
MAX_RATE_TIMESTAMPS = 16 # Maximum number of announce timestamps to keep per destination MAX_RATE_TIMESTAMPS = 16 # Maximum number of announce timestamps to keep per destination
PERSIST_RANDOM_BLOBS = 32 # Maximum number of random blobs per destination to persist to disk
MAX_RANDOM_BLOBS = 64 # Maximum number of random blobs per destination to keep in memory
interfaces = [] # All active interfaces interfaces = [] # All active interfaces
destinations = [] # All active destinations destinations = [] # All active destinations
@@ -334,7 +336,7 @@ class Transport:
if time.time() - last_path_request > Transport.PATH_REQUEST_MI: if time.time() - last_path_request > Transport.PATH_REQUEST_MI:
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link.destination.hash)+" since an attempted link was never established", RNS.LOG_DEBUG) RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link.destination.hash)+" since an attempted link was never established", RNS.LOG_DEBUG)
if not link.destination.hash in path_requests: if not link.destination.hash in path_requests:
blocked_if = link_entry[4] blocked_if = None
path_requests[link.destination.hash] = blocked_if path_requests[link.destination.hash] = blocked_if
Transport.pending_links.remove(link) Transport.pending_links.remove(link)
@@ -723,6 +725,29 @@ class Transport:
sent = False sent = False
outbound_time = time.time() outbound_time = time.time()
generate_receipt = False
if (packet.create_receipt == True and
# Only generate receipts for DATA packets
packet.packet_type == RNS.Packet.DATA and
# Don't generate receipts for PLAIN destinations
packet.destination.type != RNS.Destination.PLAIN and
# Don't generate receipts for link-related packets
not (packet.context >= RNS.Packet.KEEPALIVE and packet.context <= RNS.Packet.LRPROOF) and
# Don't generate receipts for resource packets
not (packet.context >= RNS.Packet.RESOURCE and packet.context <= RNS.Packet.RESOURCE_RCL)):
generate_receipt = True
def packet_sent(packet):
packet.sent = True
packet.sent_at = time.time()
if generate_receipt:
packet.receipt = RNS.PacketReceipt(packet)
Transport.receipts.append(packet.receipt)
Transport.cache(packet)
# Check if we have a known path for the destination in the path table # Check if we have a known path for the destination in the path table
if packet.packet_type != RNS.Packet.ANNOUNCE and packet.destination.type != RNS.Destination.PLAIN and packet.destination.type != RNS.Destination.GROUP and packet.destination_hash in Transport.destination_table: if packet.packet_type != RNS.Packet.ANNOUNCE and packet.destination.type != RNS.Destination.PLAIN and packet.destination.type != RNS.Destination.GROUP and packet.destination_hash in Transport.destination_table:
outbound_interface = Transport.destination_table[packet.destination_hash][5] outbound_interface = Transport.destination_table[packet.destination_hash][5]
@@ -740,6 +765,7 @@ class Transport:
new_raw += packet.raw[1:2] new_raw += packet.raw[1:2]
new_raw += Transport.destination_table[packet.destination_hash][1] new_raw += Transport.destination_table[packet.destination_hash][1]
new_raw += packet.raw[2:] new_raw += packet.raw[2:]
packet_sent(packet)
Transport.transmit(outbound_interface, new_raw) Transport.transmit(outbound_interface, new_raw)
Transport.destination_table[packet.destination_hash][0] = time.time() Transport.destination_table[packet.destination_hash][0] = time.time()
sent = True sent = True
@@ -759,6 +785,7 @@ class Transport:
new_raw += packet.raw[1:2] new_raw += packet.raw[1:2]
new_raw += Transport.destination_table[packet.destination_hash][1] new_raw += Transport.destination_table[packet.destination_hash][1]
new_raw += packet.raw[2:] new_raw += packet.raw[2:]
packet_sent(packet)
Transport.transmit(outbound_interface, new_raw) Transport.transmit(outbound_interface, new_raw)
Transport.destination_table[packet.destination_hash][0] = time.time() Transport.destination_table[packet.destination_hash][0] = time.time()
sent = True sent = True
@@ -767,6 +794,7 @@ class Transport:
# directly reachable, and also on which interface, so we # directly reachable, and also on which interface, so we
# simply transmit the packet directly on that one. # simply transmit the packet directly on that one.
else: else:
packet_sent(packet)
Transport.transmit(outbound_interface, packet.raw) Transport.transmit(outbound_interface, packet.raw)
sent = True sent = True
@@ -850,7 +878,7 @@ class Transport:
interface.announce_queue = [] interface.announce_queue = []
queued_announces = True if len(interface.announce_queue) > 0 else False queued_announces = True if len(interface.announce_queue) > 0 else False
if not queued_announces and outbound_time > interface.announce_allowed_at: if not queued_announces and outbound_time > interface.announce_allowed_at and interface.bitrate != None and interface.bitrate != 0:
tx_time = (len(packet.raw)*8) / interface.bitrate tx_time = (len(packet.raw)*8) / interface.bitrate
wait_time = (tx_time / interface.announce_cap) wait_time = (tx_time / interface.announce_cap)
interface.announce_allowed_at = outbound_time + wait_time interface.announce_allowed_at = outbound_time + wait_time
@@ -933,28 +961,9 @@ class Transport:
Transport.transmit(interface, packet.raw) Transport.transmit(interface, packet.raw)
if packet.packet_type == RNS.Packet.ANNOUNCE: if packet.packet_type == RNS.Packet.ANNOUNCE:
interface.sent_announce() interface.sent_announce()
packet_sent(packet)
sent = True sent = True
if sent:
packet.sent = True
packet.sent_at = time.time()
# Don't generate receipt if it has been explicitly disabled
if (packet.create_receipt == True and
# Only generate receipts for DATA packets
packet.packet_type == RNS.Packet.DATA and
# Don't generate receipts for PLAIN destinations
packet.destination.type != RNS.Destination.PLAIN and
# Don't generate receipts for link-related packets
not (packet.context >= RNS.Packet.KEEPALIVE and packet.context <= RNS.Packet.LRPROOF) and
# Don't generate receipts for resource packets
not (packet.context >= RNS.Packet.RESOURCE and packet.context <= RNS.Packet.RESOURCE_RCL)):
packet.receipt = RNS.PacketReceipt(packet)
Transport.receipts.append(packet.receipt)
Transport.cache(packet)
Transport.jobs_locked = False Transport.jobs_locked = False
return sent return sent
@@ -1314,7 +1323,8 @@ class Transport:
announce_entry[6] += 1 announce_entry[6] += 1
if announce_entry[6] >= Transport.LOCAL_REBROADCASTS_MAX: if announce_entry[6] >= Transport.LOCAL_REBROADCASTS_MAX:
RNS.log("Max local rebroadcasts of announce for "+RNS.prettyhexrep(packet.destination_hash)+" reached, dropping announce from our table", RNS.LOG_DEBUG) RNS.log("Max local rebroadcasts of announce for "+RNS.prettyhexrep(packet.destination_hash)+" reached, dropping announce from our table", RNS.LOG_DEBUG)
Transport.announce_table.pop(packet.destination_hash) if packet.destination_hash in Transport.announce_table:
Transport.announce_table.pop(packet.destination_hash)
if packet.hops-1 == announce_entry[4]+1 and announce_entry[2] > 0: if packet.hops-1 == announce_entry[4]+1 and announce_entry[2] > 0:
now = time.time() now = time.time()
@@ -1463,6 +1473,7 @@ class Transport:
expires = now + Transport.PATHFINDER_E expires = now + Transport.PATHFINDER_E
random_blobs.append(random_blob) random_blobs.append(random_blob)
random_blobs = random_blobs[-Transport.MAX_RANDOM_BLOBS:]
if (RNS.Reticulum.transport_enabled() or Transport.from_local_client(packet)) and packet.context != RNS.Packet.PATH_RESPONSE: if (RNS.Reticulum.transport_enabled() or Transport.from_local_client(packet)) and packet.context != RNS.Packet.PATH_RESPONSE:
# Insert announce into announce table for retransmission # Insert announce into announce table for retransmission
@@ -1737,9 +1748,6 @@ class Transport:
if receipt.hash == proof_hash: if receipt.hash == proof_hash:
receipt_validated = receipt.validate_proof_packet(packet) receipt_validated = receipt.validate_proof_packet(packet)
else: else:
# TODO: This looks like it should actually
# be rewritten when implicit proofs are added.
# In case of an implicit proof, we have # In case of an implicit proof, we have
# to check every single outstanding receipt # to check every single outstanding receipt
receipt_validated = receipt.validate_proof_packet(packet) receipt_validated = receipt.validate_proof_packet(packet)
@@ -2578,7 +2586,7 @@ class Transport:
received_from = de[1] received_from = de[1]
hops = de[2] hops = de[2]
expires = de[3] expires = de[3]
random_blobs = de[4] random_blobs = de[4][-Transport.PERSIST_RANDOM_BLOBS:]
packet_hash = de[6].get_hash() packet_hash = de[6].get_hash()
serialised_entry = [ serialised_entry = [
+89 -8
View File
@@ -64,19 +64,22 @@ def main():
parser.add_argument("--config", metavar="path", action="store", default=None, help="path to alternative Reticulum config directory", type=str) parser.add_argument("--config", metavar="path", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
parser.add_argument("-i", "--identity", metavar="identity", action="store", default=None, help="hexadecimal Reticulum Destination hash or path to Identity file", type=str) parser.add_argument("-i", "--identity", metavar="identity", action="store", default=None, help="hexadecimal Reticulum Destination hash or path to Identity file", type=str)
parser.add_argument("-g", "--generate", metavar="path", action="store", default=None, help="generate a new Identity") parser.add_argument("-g", "--generate", metavar="file", action="store", default=None, help="generate a new Identity")
parser.add_argument("-m", "--import", dest="import_str", metavar="identity_data", action="store", default=None, help="import Reticulum identity in hex, base32 or base64 format", type=str)
parser.add_argument("-x", "--export", action="store_true", default=None, help="export identity to hex, base32 or base64 format")
parser.add_argument("-v", "--verbose", action="count", default=0, help="increase verbosity") parser.add_argument("-v", "--verbose", action="count", default=0, help="increase verbosity")
parser.add_argument("-q", "--quiet", action="count", default=0, help="decrease verbosity") parser.add_argument("-q", "--quiet", action="count", default=0, help="decrease verbosity")
parser.add_argument("-a", "--announce", metavar="aspects", action="store", default=None, help="announce a destination based on this Identity") parser.add_argument("-a", "--announce", metavar="aspects", action="store", default=None, help="announce a destination based on this Identity")
parser.add_argument("-H", "--hash", metavar="aspects", action="store", default=None, help="show destination hashes for other aspects for this Identity") parser.add_argument("-H", "--hash", metavar="aspects", action="store", default=None, help="show destination hashes for other aspects for this Identity")
parser.add_argument("-e", "--encrypt", metavar="path", action="store", default=None, help="encrypt file") parser.add_argument("-e", "--encrypt", metavar="file", action="store", default=None, help="encrypt file")
parser.add_argument("-d", "--decrypt", metavar="path", action="store", default=None, help="decrypt file") parser.add_argument("-d", "--decrypt", metavar="file", action="store", default=None, help="decrypt file")
parser.add_argument("-s", "--sign", metavar="path", action="store", default=None, help="sign file") parser.add_argument("-s", "--sign", metavar="path", action="store", default=None, help="sign file")
parser.add_argument("-V", "--validate", metavar="path", action="store", default=None, help="validate signature") parser.add_argument("-V", "--validate", metavar="path", action="store", default=None, help="validate signature")
parser.add_argument("-r", "--read", metavar="path", action="store", default=None, help="input file path", type=str) parser.add_argument("-r", "--read", metavar="file", action="store", default=None, help="input file path", type=str)
parser.add_argument("-w", "--write", metavar="path", action="store", default=None, help="output file path", type=str) parser.add_argument("-w", "--write", metavar="file", action="store", default=None, help="output file path", type=str)
parser.add_argument("-f", "--force", action="store_true", default=None, help="write output even if it overwrites existing files") parser.add_argument("-f", "--force", action="store_true", default=None, help="write output even if it overwrites existing files")
parser.add_argument("-I", "--stdin", action="store_true", default=False, help=argparse.SUPPRESS) # "read input from STDIN instead of file" parser.add_argument("-I", "--stdin", action="store_true", default=False, help=argparse.SUPPRESS) # "read input from STDIN instead of file"
parser.add_argument("-O", "--stdout", action="store_true", default=False, help=argparse.SUPPRESS) # help="write output to STDOUT instead of file", parser.add_argument("-O", "--stdout", action="store_true", default=False, help=argparse.SUPPRESS) # help="write output to STDOUT instead of file",
@@ -86,7 +89,8 @@ def main():
parser.add_argument("-p", "--print-identity", action="store_true", default=False, help="print identity info and exit") parser.add_argument("-p", "--print-identity", action="store_true", default=False, help="print identity info and exit")
parser.add_argument("-P", "--print-private", action="store_true", default=False, help="allow displaying private keys") parser.add_argument("-P", "--print-private", action="store_true", default=False, help="allow displaying private keys")
parser.add_argument("-b", "--base64", action="store_true", default=False, help=argparse.SUPPRESS) # help="Use base64-encoded input and output") parser.add_argument("-b", "--base64", action="store_true", default=False, help="Use base64-encoded input and output")
parser.add_argument("-B", "--base32", action="store_true", default=False, help="Use base32-encoded input and output")
parser.add_argument("--version", action="version", version="rnid {version}".format(version=__version__)) parser.add_argument("--version", action="version", version="rnid {version}".format(version=__version__))
@@ -110,6 +114,59 @@ def main():
args.read = args.sign args.read = args.sign
identity_str = args.identity identity_str = args.identity
if args.import_str:
identity_bytes = None
try:
if args.base64:
identity_bytes = base64.urlsafe_b64decode(args.import_str)
elif args.base32:
identity_bytes = base64.b32decode(args.import_str)
else:
identity_bytes = bytes.fromhex(args.import_str)
except Exception as e:
print("Invalid identity data specified for import: "+str(e))
exit(41)
try:
identity = RNS.Identity.from_bytes(identity_bytes)
except Exception as e:
print("Could not create Reticulum identity from specified data: "+str(e))
exit(42)
RNS.log("Identity imported")
if args.base64:
RNS.log("Public Key : "+base64.urlsafe_b64encode(identity.get_public_key()).decode("utf-8"))
elif args.base32:
RNS.log("Public Key : "+base64.b32encode(identity.get_public_key()).decode("utf-8"))
else:
RNS.log("Public Key : "+RNS.hexrep(identity.get_public_key(), delimit=False))
if identity.prv:
if args.print_private:
if args.base64:
RNS.log("Private Key : "+base64.urlsafe_b64encode(identity.get_private_key()).decode("utf-8"))
elif args.base32:
RNS.log("Private Key : "+base64.b32encode(identity.get_private_key()).decode("utf-8"))
else:
RNS.log("Private Key : "+RNS.hexrep(identity.get_private_key(), delimit=False))
else:
RNS.log("Private Key : Hidden")
if args.write:
try:
wp = os.path.expanduser(args.write)
if not os.path.isfile(wp) or args.force:
identity.to_file(wp)
RNS.log("Wrote imported identity to "+str(args.write))
else:
print("File "+str(wp)+" already exists, not overwriting")
exit(43)
except Exception as e:
print("Error while writing imported identity to file: "+str(e))
exit(44)
exit(0)
if not args.generate and not identity_str: if not args.generate and not identity_str:
print("\nNo identity provided, cannot continue\n") print("\nNo identity provided, cannot continue\n")
parser.print_help() parser.print_help()
@@ -246,14 +303,38 @@ def main():
exit(0) exit(0)
if args.print_identity: if args.print_identity:
RNS.log("Public Key : "+RNS.hexrep(identity.pub_bytes, delimit=False)) if args.base64:
RNS.log("Public Key : "+base64.urlsafe_b64encode(identity.get_public_key()).decode("utf-8"))
elif args.base32:
RNS.log("Public Key : "+base64.b32encode(identity.get_public_key()).decode("utf-8"))
else:
RNS.log("Public Key : "+RNS.hexrep(identity.get_public_key(), delimit=False))
if identity.prv: if identity.prv:
if args.print_private: if args.print_private:
RNS.log("Private Key : "+RNS.hexrep(identity.prv_bytes, delimit=False)) if args.base64:
RNS.log("Private Key : "+base64.urlsafe_b64encode(identity.get_private_key()).decode("utf-8"))
elif args.base32:
RNS.log("Private Key : "+base64.b32encode(identity.get_private_key()).decode("utf-8"))
else:
RNS.log("Private Key : "+RNS.hexrep(identity.get_private_key(), delimit=False))
else: else:
RNS.log("Private Key : Hidden") RNS.log("Private Key : Hidden")
exit(0) exit(0)
if args.export:
if identity.prv:
if args.base64:
RNS.log("Exported Identity : "+base64.urlsafe_b64encode(identity.get_private_key()).decode("utf-8"))
elif args.base32:
RNS.log("Exported Identity : "+base64.b32encode(identity.get_private_key()).decode("utf-8"))
else:
RNS.log("Exported Identity : "+RNS.hexrep(identity.get_private_key(), delimit=False))
else:
RNS.log("Identity doesn't hold a private key, cannot export")
exit(50)
exit(0)
if args.validate: if args.validate:
if not args.read and args.validate.lower().endswith("."+SIG_EXT): if not args.read and args.validate.lower().endswith("."+SIG_EXT):
args.read = str(args.validate).replace("."+SIG_EXT, "") args.read = str(args.validate).replace("."+SIG_EXT, "")
+249 -82
View File
@@ -42,8 +42,8 @@ RNS.logtimefmt = "%H:%M:%S"
RNS.compact_log_fmt = True RNS.compact_log_fmt = True
program_version = "2.1.3" program_version = "2.1.3"
eth_addr = "0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a" eth_addr = "0xFDabC71AC4c0C78C95aDDDe3B4FA19d6273c5E73"
btc_addr = "3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq" btc_addr = "35G9uWVzrpJJibzUwpNUQGQNFzLirhrYAH"
xmr_addr = "87HcDx6jRSkMQ9nPRd5K9hGGpZLn2s7vWETjMaVM5KfV4TD36NcYa8J8WSxhTSvBzzFpqDwp2fg5GX2moZ7VAP9QMZCZGET" xmr_addr = "87HcDx6jRSkMQ9nPRd5K9hGGpZLn2s7vWETjMaVM5KfV4TD36NcYa8J8WSxhTSvBzzFpqDwp2fg5GX2moZ7VAP9QMZCZGET"
rnode = None rnode = None
@@ -120,12 +120,16 @@ class KISS():
class ROM(): class ROM():
PLATFORM_AVR = 0x90 PLATFORM_AVR = 0x90
PLATFORM_ESP32 = 0x80 PLATFORM_ESP32 = 0x80
PLATFORM_NRF52 = 0x70
MCU_1284P = 0x91 MCU_1284P = 0x91
MCU_2560 = 0x92 MCU_2560 = 0x92
MCU_ESP32 = 0x81 MCU_ESP32 = 0x81
MCU_NRF52 = 0x71
PRODUCT_RNODE = 0x03 PRODUCT_RNODE = 0x03
MODEL_A1 = 0xA1
MODEL_A6 = 0xA6
MODEL_A4 = 0xA4 MODEL_A4 = 0xA4
MODEL_A9 = 0xA9 MODEL_A9 = 0xA9
MODEL_A3 = 0xA3 MODEL_A3 = 0xA3
@@ -144,6 +148,8 @@ class ROM():
PRODUCT_T32_21 = 0xB1 PRODUCT_T32_21 = 0xB1
MODEL_B4 = 0xB4 MODEL_B4 = 0xB4
MODEL_B9 = 0xB9 MODEL_B9 = 0xB9
MODEL_B4_TCXO = 0x04
MODEL_B9_TCXO = 0x09
PRODUCT_H32_V2 = 0xC0 PRODUCT_H32_V2 = 0xC0
MODEL_C4 = 0xC4 MODEL_C4 = 0xC4
@@ -152,6 +158,8 @@ class ROM():
PRODUCT_TBEAM = 0xE0 PRODUCT_TBEAM = 0xE0
MODEL_E4 = 0xE4 MODEL_E4 = 0xE4
MODEL_E9 = 0xE9 MODEL_E9 = 0xE9
MODEL_E3 = 0xE3
MODEL_E8 = 0xE8
PRODUCT_HMBRW = 0xF0 PRODUCT_HMBRW = 0xF0
MODEL_FF = 0xFF MODEL_FF = 0xFF
@@ -182,6 +190,7 @@ class ROM():
BOARD_GENERIC_ESP32 = 0x35 BOARD_GENERIC_ESP32 = 0x35
BOARD_LORA32_V2_0 = 0x36 BOARD_LORA32_V2_0 = 0x36
BOARD_LORA32_V2_1 = 0x37 BOARD_LORA32_V2_1 = 0x37
BOARD_RAK4630 = 0x51
mapped_product = ROM.PRODUCT_RNODE mapped_product = ROM.PRODUCT_RNODE
products = { products = {
@@ -197,33 +206,41 @@ products = {
platforms = { platforms = {
ROM.PLATFORM_AVR: "AVR", ROM.PLATFORM_AVR: "AVR",
ROM.PLATFORM_ESP32:"ESP32", ROM.PLATFORM_ESP32:"ESP32",
ROM.PLATFORM_NRF52:"NRF52",
} }
mcus = { mcus = {
ROM.MCU_1284P: "ATmega1284P", ROM.MCU_1284P: "ATmega1284P",
ROM.MCU_2560:"ATmega2560", ROM.MCU_2560:"ATmega2560",
ROM.MCU_ESP32:"Espressif Systems ESP32", ROM.MCU_ESP32:"Espressif Systems ESP32",
ROM.MCU_NRF52:"Nordic nRF52840",
} }
models = { models = {
0xA4: [410000000, 525000000, 14, "410 - 525 MHz", "rnode_firmware.hex"], 0xA4: [410000000, 525000000, 14, "410 - 525 MHz", "rnode_firmware.hex", "SX1278"],
0xA9: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware.hex"], 0xA9: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware.hex", "SX1276"],
0xA2: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng21.zip"], 0xA1: [410000000, 525000000, 22, "410 - 525 MHz", "rnode_firmware_t3s3.zip", "SX1268"],
0xA7: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng21.zip"], 0xA6: [820000000, 1020000000, 22, "820 - 960 MHz", "rnode_firmware_t3s3.zip", "SX1262"],
0xA3: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng20.zip"], 0xA2: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng21.zip", "SX1278"],
0xA8: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng20.zip"], 0xA7: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng21.zip", "SX1276"],
0xB3: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v20.zip"], 0xA3: [410000000, 525000000, 17, "410 - 525 MHz", "rnode_firmware_ng20.zip", "SX1278"],
0xB8: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v20.zip"], 0xA8: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware_ng20.zip", "SX1276"],
0xB4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v21.zip"], 0xB3: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v20.zip", "SX1278"],
0xB9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v21.zip"], 0xB8: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v20.zip", "SX1276"],
0xBA: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v10.zip"], 0xB4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v21.zip", "SX1278"],
0xBB: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v10.zip"], 0xB9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v21.zip", "SX1276"],
0xC4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_heltec32v2.zip"], 0x04: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v21_tcxo.zip", "SX1278"],
0xC9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_heltec32v2.zip"], 0x09: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v21_tcxo.zip", "SX1276"],
0xE4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_tbeam.zip"], 0xBA: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_lora32v10.zip", "SX1278"],
0xE9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_tbeam.zip"], 0xBB: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_lora32v10.zip", "SX1276"],
0xFE: [100000000, 1100000000, 17, "(Band capabilities unknown)", None], 0xC4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_heltec32v2.zip", "SX1278"],
0xFF: [100000000, 1100000000, 14, "(Band capabilities unknown)", None], 0xC9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_heltec32v2.zip", "SX1276"],
0xE4: [420000000, 520000000, 17, "420 - 520 MHz", "rnode_firmware_tbeam.zip", "SX1278"],
0xE9: [850000000, 950000000, 17, "850 - 950 MHz", "rnode_firmware_tbeam.zip", "SX1276"],
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"],
0xFE: [100000000, 1100000000, 17, "(Band capabilities unknown)", None, "Unknown"],
0xFF: [100000000, 1100000000, 14, "(Band capabilities unknown)", None, "Unknown"],
} }
CNF_DIR = None CNF_DIR = None
@@ -516,7 +533,7 @@ class RNode():
if (len(command_buffer) == 4): if (len(command_buffer) == 4):
self.r_stat_tx = ord(command_buffer[0]) << 24 | ord(command_buffer[1]) << 16 | ord(command_buffer[2]) << 8 | ord(command_buffer[3]) self.r_stat_tx = ord(command_buffer[0]) << 24 | ord(command_buffer[1]) << 16 | ord(command_buffer[2]) << 8 | ord(command_buffer[3])
elif (command == KISS.CMD_STAT_RSSI): elif (command == KISS.CMD_STAT_RSSI):
self.r_stat_rssi = byte-RNodeInterface.RSSI_OFFSET self.r_stat_rssi = byte-157 # RSSI Offset
elif (command == KISS.CMD_STAT_SNR): elif (command == KISS.CMD_STAT_SNR):
self.r_stat_snr = int.from_bytes(bytes([byte]), byteorder="big", signed=True) * 0.25 self.r_stat_snr = int.from_bytes(bytes([byte]), byteorder="big", signed=True) * 0.25
elif (command == KISS.CMD_RANDOM): elif (command == KISS.CMD_RANDOM):
@@ -928,6 +945,7 @@ class RNode():
except Exception as e: except Exception as e:
self.provisioned = False self.provisioned = False
RNS.log("Invalid EEPROM data, could not parse device EEPROM.") RNS.log("Invalid EEPROM data, could not parse device EEPROM.")
RNS.log("The contained exception was: "+str(e))
def device_probe(self): def device_probe(self):
@@ -1018,6 +1036,10 @@ def ensure_firmware_file(fw_filename):
file = open(UPD_DIR+"/"+fw_filename+".version.latest", "rb") file = open(UPD_DIR+"/"+fw_filename+".version.latest", "rb")
release_info = file.read().decode("utf-8").strip() release_info = file.read().decode("utf-8").strip()
selected_version = release_info.split()[0] selected_version = release_info.split()[0]
if selected_version == "not":
RNS.log("No valid version found for this board, exiting.")
exit(199)
selected_hash = release_info.split()[1] selected_hash = release_info.split()[1]
if not os.path.isdir(UPD_DIR+"/"+selected_version): if not os.path.isdir(UPD_DIR+"/"+selected_version):
os.makedirs(UPD_DIR+"/"+selected_version) os.makedirs(UPD_DIR+"/"+selected_version)
@@ -1169,15 +1191,15 @@ def main():
parser.add_argument("--version", action="store_true", help="Print program version and exit") parser.add_argument("--version", action="store_true", help="Print program version and exit")
parser.add_argument("-f", "--flash", action="store_true", help=argparse.SUPPRESS) # Flash firmware and bootstrap EEPROM parser.add_argument("-f", "--flash", action="store_true", help="Flash firmware and bootstrap EEPROM")
parser.add_argument("-r", "--rom", action="store_true", help=argparse.SUPPRESS) # Bootstrap EEPROM without flashing firmware parser.add_argument("-r", "--rom", action="store_true", help="Bootstrap EEPROM without flashing firmware")
parser.add_argument("-k", "--key", action="store_true", help=argparse.SUPPRESS) # Generate a new signing key and exit parser.add_argument("-k", "--key", action="store_true", help="Generate a new signing key and exit") #
parser.add_argument("-S", "--sign", action="store_true", help=argparse.SUPPRESS) # Display public part of signing key parser.add_argument("-S", "--sign", action="store_true", help="Display public part of signing key")
parser.add_argument("-H", "--firmware-hash", action="store", help=argparse.SUPPRESS) # Display public part of signing key parser.add_argument("-H", "--firmware-hash", action="store", help="Display installed firmware hash")
parser.add_argument("--platform", action="store", metavar="platform", type=str, default=None, help=argparse.SUPPRESS) # Platform specification for device bootstrap parser.add_argument("--platform", action="store", metavar="platform", type=str, default=None, help="Platform specification for device bootstrap")
parser.add_argument("--product", action="store", metavar="product", type=str, default=None, help=argparse.SUPPRESS) # Product specification for device bootstrap parser.add_argument("--product", action="store", metavar="product", type=str, default=None, help="Product specification for device bootstrap") #
parser.add_argument("--model", action="store", metavar="model", type=str, default=None, help=argparse.SUPPRESS) # Model code for device bootstrap parser.add_argument("--model", action="store", metavar="model", type=str, default=None, help="Model code for device bootstrap")
parser.add_argument("--hwrev", action="store", metavar="revision", type=int, default=None, help=argparse.SUPPRESS) # Hardware revision for device bootstrap parser.add_argument("--hwrev", action="store", metavar="revision", type=int, default=None, help="Hardware revision for device bootstrap")
parser.add_argument("port", nargs="?", default=None, help="serial port where RNode is attached", type=str) parser.add_argument("port", nargs="?", default=None, help="serial port where RNode is attached", type=str)
args = parser.parse_args() args = parser.parse_args()
@@ -1497,6 +1519,7 @@ def main():
print("[5] LilyGO LoRa32 v1.0") print("[5] LilyGO LoRa32 v1.0")
print("[6] LilyGO T-Beam") print("[6] LilyGO T-Beam")
print("[7] Heltec LoRa32 v2") print("[7] Heltec LoRa32 v2")
print("[8] LilyGO LoRa T3S3")
print(" .") print(" .")
print(" / \\ Select one of these options if you want to easily turn") print(" / \\ Select one of these options if you want to easily turn")
print(" | a supported development board into an RNode.") print(" | a supported development board into an RNode.")
@@ -1507,7 +1530,8 @@ def main():
selected_product = None selected_product = None
try: try:
c_dev = int(input()) c_dev = int(input())
if c_dev < 1 or c_dev > 7: c_mod = False
if c_dev < 1 or c_dev > 8:
raise ValueError() raise ValueError()
elif c_dev == 1: elif c_dev == 1:
selected_product = ROM.PRODUCT_RNODE selected_product = ROM.PRODUCT_RNODE
@@ -1536,8 +1560,7 @@ def main():
print(" T-Beam RNode Installer") print(" T-Beam RNode Installer")
print("") print("")
print("The RNode firmware can currently be installed on T-Beam devices using the") print("The RNode firmware can currently be installed on T-Beam devices using the")
print("SX1276 and SX1278 transceiver chips. Support for devices with the newer") print("SX1276, SX1278, SX1262 and SX1268 transceiver chips.")
print("SX1262 and SX1268 chips is in development.")
print("") print("")
print("Important! Using RNode firmware on T-Beam devices should currently be") 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("considered experimental. It is not intended for production or critical use.")
@@ -1608,6 +1631,23 @@ def main():
print("who would like to experiment with it. Hit enter to continue.") print("who would like to experiment with it. Hit enter to continue.")
print("---------------------------------------------------------------------------") print("---------------------------------------------------------------------------")
input() input()
elif c_dev == 8:
selected_product = ROM.PRODUCT_RNODE
c_mod = True
clear()
print("")
print("---------------------------------------------------------------------------")
print(" LilyGO LoRa32 T3S3 RNode Installer")
print("")
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("---------------------------------------------------------------------------")
input()
except Exception as e: except Exception as e:
print("That device type does not exist, exiting now.") print("That device type does not exist, exiting now.")
exit() exit()
@@ -1660,53 +1700,86 @@ def main():
elif selected_product == ROM.PRODUCT_RNODE: elif selected_product == ROM.PRODUCT_RNODE:
selected_mcu = ROM.MCU_1284P if not c_mod:
print("\nWhat model is this RNode?\n") selected_mcu = ROM.MCU_1284P
print("[1] Handheld v2.x RNode, 410 - 525 MHz") print("\nWhat model is this RNode?\n")
print("[2] Handheld v2.x RNode, 820 - 1020 MHz") print("[1] Handheld v2.1 RNode, 410 - 525 MHz")
print("") print("[2] Handheld v2.1 RNode, 820 - 1020 MHz")
print("[3] Original v1.x RNode, 410 - 525 MHz") print("")
print("[4] Original v1.x RNode, 820 - 1020 MHz") print("[3] Original v1.x RNode, 410 - 525 MHz")
# print("[5] Prototype v2 RNode, 410 - 525 MHz") print("[4] Original v1.x RNode, 820 - 1020 MHz")
# print("[6] Prototype v2 RNode, 820 - 1020 MHz") print("")
print("\n? ", end="") print("[5] Prototype v2.2 RNode, 410 - 525 MHz")
try: print("[6] Prototype v2.2 RNode, 820 - 1020 MHz")
c_model = int(input()) # print("[5] Prototype v2 RNode, 410 - 525 MHz")
if c_model < 1 or c_model > 6: # print("[6] Prototype v2 RNode, 820 - 1020 MHz")
raise ValueError() print("\n? ", end="")
elif c_model == 3: try:
selected_model = ROM.MODEL_A4 c_model = int(input())
selected_platform = ROM.PLATFORM_AVR if c_model < 1 or c_model > 6:
elif c_model == 4: raise ValueError()
selected_model = ROM.MODEL_A9 elif c_model == 1:
selected_platform = ROM.PLATFORM_AVR selected_model = ROM.MODEL_A2
elif c_model == 1: selected_mcu = ROM.MCU_ESP32
selected_model = ROM.MODEL_A2 selected_platform = ROM.PLATFORM_ESP32
selected_mcu = ROM.MCU_ESP32 elif c_model == 2:
selected_platform = ROM.PLATFORM_ESP32 selected_model = ROM.MODEL_A7
elif c_model == 2: selected_mcu = ROM.MCU_ESP32
selected_model = ROM.MODEL_A7 selected_platform = ROM.PLATFORM_ESP32
selected_mcu = ROM.MCU_ESP32 elif c_model == 3:
selected_platform = ROM.PLATFORM_ESP32 selected_model = ROM.MODEL_A4
# elif c_model == 5: selected_platform = ROM.PLATFORM_AVR
# selected_model = ROM.MODEL_A3 elif c_model == 4:
# selected_mcu = ROM.MCU_ESP32 selected_model = ROM.MODEL_A9
# selected_platform = ROM.PLATFORM_ESP32 selected_platform = ROM.PLATFORM_AVR
# elif c_model == 6: elif c_model == 5:
# selected_model = ROM.MODEL_A8 selected_model = ROM.MODEL_A1
# selected_mcu = ROM.MCU_ESP32 selected_mcu = ROM.MCU_ESP32
# selected_platform = ROM.PLATFORM_ESP32 selected_platform = ROM.PLATFORM_ESP32
except Exception as e: elif c_model == 6:
print("That model does not exist, exiting now.") selected_model = ROM.MODEL_A6
exit() selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
# elif c_model == 5:
# selected_model = ROM.MODEL_A3
# selected_mcu = ROM.MCU_ESP32
# selected_platform = ROM.PLATFORM_ESP32
# elif c_model == 6:
# selected_model = ROM.MODEL_A8
# selected_mcu = ROM.MCU_ESP32
# selected_platform = ROM.PLATFORM_ESP32
except Exception as e:
print("That model does not exist, exiting now.")
exit()
else:
print("\nWhat model is this T3S3?\n")
print("[1] 410 - 525 MHz (with SX1268 chip)")
print("[2] 820 - 1020 MHz (with SX1268 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_A1
selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 2:
selected_model = ROM.MODEL_A6
selected_mcu = ROM.MCU_ESP32
selected_platform = ROM.PLATFORM_ESP32
except Exception as e:
print("That model does not exist, exiting now.")
exit()
elif selected_product == ROM.PRODUCT_TBEAM: elif selected_product == ROM.PRODUCT_TBEAM:
selected_mcu = ROM.MCU_ESP32 selected_mcu = ROM.MCU_ESP32
print("\nWhat band is this T-Beam for?\n") print("\nWhat band is this T-Beam for?\n")
print("[1] 433 MHz") print("[1] 433 MHz (with SX1278 chip)")
print("[2] 868 MHz") print("[2] 868/915/923 MHz (with SX1276 chip)")
print("[3] 915 MHz") print("");
print("[4] 923 MHz") print("[3] 433 MHz (with SX1268 chip)")
print("[4] 868/915/923 MHz (with SX1262 chip)")
print("\n? ", end="") print("\n? ", end="")
try: try:
c_model = int(input()) c_model = int(input())
@@ -1715,9 +1788,15 @@ def main():
elif c_model == 1: elif c_model == 1:
selected_model = ROM.MODEL_E4 selected_model = ROM.MODEL_E4
selected_platform = ROM.PLATFORM_ESP32 selected_platform = ROM.PLATFORM_ESP32
elif c_model > 1: elif c_model == 2:
selected_model = ROM.MODEL_E9 selected_model = ROM.MODEL_E9
selected_platform = ROM.PLATFORM_ESP32 selected_platform = ROM.PLATFORM_ESP32
elif c_model == 3:
selected_model = ROM.MODEL_E3
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 4:
selected_model = ROM.MODEL_E8
selected_platform = ROM.PLATFORM_ESP32
except Exception as e: except Exception as e:
print("That band does not exist, exiting now.") print("That band does not exist, exiting now.")
exit() exit()
@@ -1770,9 +1849,9 @@ def main():
selected_mcu = ROM.MCU_ESP32 selected_mcu = ROM.MCU_ESP32
print("\nWhat band is this LoRa32 for?\n") print("\nWhat band is this LoRa32 for?\n")
print("[1] 433 MHz") print("[1] 433 MHz")
print("[2] 868 MHz") print("[2] 868/915/923 MHz")
print("[3] 915 MHz") print("[3] 433 MHz, with TCXO")
print("[4] 923 MHz") print("[4] 868/915/923 MHz, with TCXO")
print("\n? ", end="") print("\n? ", end="")
try: try:
c_model = int(input()) c_model = int(input())
@@ -1781,9 +1860,15 @@ def main():
elif c_model == 1: elif c_model == 1:
selected_model = ROM.MODEL_B4 selected_model = ROM.MODEL_B4
selected_platform = ROM.PLATFORM_ESP32 selected_platform = ROM.PLATFORM_ESP32
elif c_model > 1: elif c_model == 2:
selected_model = ROM.MODEL_B9 selected_model = ROM.MODEL_B9
selected_platform = ROM.PLATFORM_ESP32 selected_platform = ROM.PLATFORM_ESP32
elif c_model == 3:
selected_model = ROM.MODEL_B4_TCXO
selected_platform = ROM.PLATFORM_ESP32
elif c_model == 4:
selected_model = ROM.MODEL_B9_TCXO
selected_platform = ROM.PLATFORM_ESP32
except Exception as e: except Exception as e:
print("That band does not exist, exiting now.") print("That band does not exist, exiting now.")
exit() exit()
@@ -2098,6 +2183,42 @@ def main():
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.bin", "0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.partitions", "0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.partitions",
] ]
elif fw_filename == "rnode_firmware_tbeam_sx1262.zip":
if numeric_version >= 1.55:
return [
sys.executable, flasher,
"--chip", "esp32",
"--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_sx1262.boot_app0",
"0x1000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_sx1262.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_sx1262.bin",
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam_sx1262.partitions",
]
else:
return [
sys.executable, flasher,
"--chip", "esp32",
"--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.boot_app0",
"0x1000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_tbeam.partitions",
]
elif fw_filename == "rnode_firmware_lora32v10.zip": elif fw_filename == "rnode_firmware_lora32v10.zip":
if numeric_version >= 1.59: if numeric_version >= 1.59:
return [ return [
@@ -2206,6 +2327,24 @@ def main():
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21.bin", "0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21.partitions", "0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21.partitions",
] ]
elif fw_filename == "rnode_firmware_lora32v21_tcxo.zip":
return [
sys.executable, flasher,
"--chip", "esp32",
"--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_lora32v21_tcxo.boot_app0",
"0x1000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21_tcxo.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21_tcxo.bin",
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_lora32v21_tcxo.partitions",
]
elif fw_filename == "rnode_firmware_heltec32v2.zip": elif fw_filename == "rnode_firmware_heltec32v2.zip":
if numeric_version >= 1.55: if numeric_version >= 1.55:
return [ return [
@@ -2386,6 +2525,24 @@ def main():
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_ng21.bin", "0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_ng21.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_ng21.partitions", "0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_ng21.partitions",
] ]
elif fw_filename == "rnode_firmware_t3s3.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.boot_app0",
"0x1000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3.bootloader",
"0x10000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3.bin",
"0x210000",UPD_DIR+"/"+selected_version+"/console_image.bin",
"0x8000", UPD_DIR+"/"+selected_version+"/rnode_firmware_t3s3.partitions",
]
elif fw_filename == "extracted_rnode_firmware.zip": elif fw_filename == "extracted_rnode_firmware.zip":
return [ return [
sys.executable, flasher, sys.executable, flasher,
@@ -2770,6 +2927,7 @@ def main():
RNS.log("\tFirmware version : "+rnode.version) RNS.log("\tFirmware version : "+rnode.version)
RNS.log("\tHardware revision : "+str(int(rnode.hw_rev))) RNS.log("\tHardware revision : "+str(int(rnode.hw_rev)))
RNS.log("\tSerial number : "+RNS.hexrep(rnode.serialno)) RNS.log("\tSerial number : "+RNS.hexrep(rnode.serialno))
RNS.log("\tModem chip : "+str(models[rnode.model][5]))
RNS.log("\tFrequency range : "+str(rnode.min_freq/1e6)+" MHz - "+str(rnode.max_freq/1e6)+" MHz") RNS.log("\tFrequency range : "+str(rnode.min_freq/1e6)+" MHz - "+str(rnode.max_freq/1e6)+" MHz")
RNS.log("\tMax TX power : "+str(rnode.max_output)+" dBm") RNS.log("\tMax TX power : "+str(rnode.max_output)+" dBm")
RNS.log("\tManufactured : "+timestring) RNS.log("\tManufactured : "+timestring)
@@ -2851,12 +3009,21 @@ def main():
mapped_product = ROM.PRODUCT_TBEAM mapped_product = ROM.PRODUCT_TBEAM
if mapped_model != None: if mapped_model != None:
model = mapped_model if mapped_model == ROM.MODEL_B4_TCXO:
model = ROM.MODEL_B4
elif mapped_model == ROM.MODEL_B9_TCXO:
model = ROM.MODEL_B9
else:
model = mapped_model
else: else:
if args.model == "a4": if args.model == "a4":
model = ROM.MODEL_A4 model = ROM.MODEL_A4
elif args.model == "a9": elif args.model == "a9":
model = ROM.MODEL_A9 model = ROM.MODEL_A9
elif args.model == "a1":
model = ROM.MODEL_A1
elif args.model == "a6":
model = ROM.MODEL_A6
elif args.model == "e4": elif args.model == "e4":
model = ROM.MODEL_E4 model = ROM.MODEL_E4
elif args.model == "e9": elif args.model == "e9":
+10 -4
View File
@@ -33,7 +33,7 @@ from RNS._version import __version__
DEFAULT_PROBE_SIZE = 16 DEFAULT_PROBE_SIZE = 16
DEFAULT_TIMEOUT = 12 DEFAULT_TIMEOUT = 12
def program_setup(configdir, destination_hexhash, size=None, full_name = None, verbosity = 0, timeout=None, probes=1): def program_setup(configdir, destination_hexhash, size=None, full_name = None, verbosity = 0, timeout=None, wait=0, probes=1):
if size == None: size = DEFAULT_PROBE_SIZE if size == None: size = DEFAULT_PROBE_SIZE
if full_name == None: if full_name == None:
print("The full destination name including application name aspects must be specified for the destination") print("The full destination name including application name aspects must be specified for the destination")
@@ -100,6 +100,9 @@ def program_setup(configdir, destination_hexhash, size=None, full_name = None, v
replies = 0 replies = 0
while probes: while probes:
if sent > 0:
time.sleep(wait)
try: try:
probe = RNS.Packet(request_destination, os.urandom(size)) probe = RNS.Packet(request_destination, os.urandom(size))
probe.pack() probe.pack()
@@ -129,7 +132,7 @@ def program_setup(configdir, destination_hexhash, size=None, full_name = None, v
i = (i+1)%len(syms) i = (i+1)%len(syms)
if time.time() > _timeout: if time.time() > _timeout:
print("\r \rProbe timed out") print("\r \rProbe timed out")
else: else:
print("\b\b ") print("\b\b ")
@@ -175,11 +178,11 @@ def program_setup(configdir, destination_hexhash, size=None, full_name = None, v
reception_stats += " [SNR "+str(receipt.proof_packet.snr)+" dB]" reception_stats += " [SNR "+str(receipt.proof_packet.snr)+" dB]"
print( print(
"Valid reply received from "+ "Valid reply from "+
RNS.prettyhexrep(receipt.destination.hash)+ RNS.prettyhexrep(receipt.destination.hash)+
"\nRound-trip time is "+rttstring+ "\nRound-trip time is "+rttstring+
" over "+str(hops)+" hop"+ms+ " over "+str(hops)+" hop"+ms+
reception_stats reception_stats+"\n"
) )
else: else:
@@ -203,6 +206,7 @@ def main():
parser.add_argument("-s", "--size", action="store", default=None, help="size of probe packet payload in bytes", type=int) parser.add_argument("-s", "--size", action="store", default=None, help="size of probe packet payload in bytes", type=int)
parser.add_argument("-n", "--probes", action="store", default=1, help="number of probes to send", type=int) parser.add_argument("-n", "--probes", action="store", default=1, help="number of probes to send", type=int)
parser.add_argument("-t", "--timeout", metavar="seconds", action="store", default=None, help="timeout before giving up", type=float) parser.add_argument("-t", "--timeout", metavar="seconds", action="store", default=None, help="timeout before giving up", type=float)
parser.add_argument("-w", "--wait", metavar="seconds", action="store", default=0, help="time between each probe", type=float)
parser.add_argument("--version", action="version", version="rnprobe {version}".format(version=__version__)) parser.add_argument("--version", action="version", version="rnprobe {version}".format(version=__version__))
parser.add_argument("full_name", nargs="?", default=None, help="full destination name in dotted notation", type=str) parser.add_argument("full_name", nargs="?", default=None, help="full destination name in dotted notation", type=str)
parser.add_argument("destination_hash", nargs="?", default=None, help="hexadecimal hash of the destination", type=str) parser.add_argument("destination_hash", nargs="?", default=None, help="hexadecimal hash of the destination", type=str)
@@ -228,6 +232,8 @@ def main():
full_name = args.full_name, full_name = args.full_name,
verbosity = args.verbose, verbosity = args.verbose,
probes = args.probes, probes = args.probes,
wait = args.wait,
timeout = args.timeout,
) )
except KeyboardInterrupt: except KeyboardInterrupt:
+6
View File
@@ -144,6 +144,12 @@ def rand():
result = instance_random.random() result = instance_random.random()
return result return result
def trace_exception(e):
import traceback
exception_info = "".join(traceback.TracebackException.from_exception(e).format())
log(f"An unhandled {str(type(e))} exception occurred: {str(e)}", LOG_ERROR)
log(exception_info, LOG_ERROR)
def hexrep(data, delimit=True): def hexrep(data, delimit=True):
try: try:
iter(data) iter(data)
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.6.4" __version__ = "0.7.2"
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,4 +1,4 @@
# Sphinx build info version 1 # 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. # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: efbb3640be4dccd745e11c4ab0e199e2 config: 0f2f9f8af8c66687a92c6541875995ff
tags: 645f666f9bcd5a90fca523b33c5a78b7 tags: 645f666f9bcd5a90fca523b33c5a78b7
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.6.4 beta', VERSION: '0.7.2 beta',
LANGUAGE: 'en', LANGUAGE: 'en',
COLLAPSE_INDEX: false, COLLAPSE_INDEX: false,
BUILDER: 'html', BUILDER: 'html',
+5 -6
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Code Examples - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Code Examples - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -3084,8 +3084,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
<span class="c1"># And set up a small job to check for</span> <span class="c1"># And set up a small job to check for</span>
<span class="c1"># a potential timeout in receiving the</span> <span class="c1"># a potential timeout in receiving the</span>
<span class="c1"># file list</span> <span class="c1"># file list</span>
<span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">filelist_timeout_job</span><span class="p">)</span> <span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">filelist_timeout_job</span><span class="p">,</span> <span class="n">daemon</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">thread</span><span class="o">.</span><span class="n">setDaemon</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="c1"># This job just sleeps for the specified</span> <span class="c1"># This job just sleeps for the specified</span>
@@ -3322,7 +3321,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /> <link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.6.4 beta documentation</title> <title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -257,7 +257,7 @@
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+6 -4
View File
@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/> <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="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.6.4 beta documentation</title> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/><title>Index - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -139,7 +139,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -165,7 +165,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -530,6 +530,8 @@
</li> </li>
</ul></td> </ul></td>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Link.no_data_for">no_data_for() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.Link.no_inbound_for">no_inbound_for() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.no_inbound_for">no_inbound_for() (RNS.Link method)</a>
</li> </li>
<li><a href="reference.html#RNS.Link.no_outbound_for">no_outbound_for() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.no_outbound_for">no_outbound_for() (RNS.Link method)</a>
@@ -735,7 +737,7 @@
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Getting Started Fast - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Getting Started Fast - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -758,7 +758,7 @@ section of this manual.</p>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Communications Hardware - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Communications Hardware - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -519,7 +519,7 @@ can be used with Reticulum. This includes virtual software modems such as
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Reticulum Network Stack 0.6.4 beta documentation</title> <title>Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="#"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="#"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -468,7 +468,7 @@ to participate in the development of Reticulum itself.</p>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Configuring Interfaces - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Configuring Interfaces - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -1106,7 +1106,7 @@ to <code class="docutils literal notranslate"><span class="pre">30</span></code>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Building Networks - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Building Networks - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -467,7 +467,7 @@ connected outliers are now an integral part of the network.</p>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
Binary file not shown.
+18 -7
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>API Reference - Reticulum Network Stack 0.6.4 beta documentation</title> <title>API Reference - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -1131,7 +1131,7 @@ statistics, you will be able to retrieve stats such as <em>RSSI</em>, <em>SNR</e
<span class="sig-name descname"><span class="pre">no_inbound_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_inbound_for" title="Permalink to this definition">#</a></dt> <span class="sig-name descname"><span class="pre">no_inbound_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_inbound_for" title="Permalink to this definition">#</a></dt>
<dd><dl class="field-list simple"> <dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt> <dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>The time in seconds since last inbound packet on the link.</p> <dd class="field-odd"><p>The time in seconds since last inbound packet on the link. This includes keepalive packets.</p>
</dd> </dd>
</dl> </dl>
</dd></dl> </dd></dl>
@@ -1141,7 +1141,17 @@ statistics, you will be able to retrieve stats such as <em>RSSI</em>, <em>SNR</e
<span class="sig-name descname"><span class="pre">no_outbound_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_outbound_for" title="Permalink to this definition">#</a></dt> <span class="sig-name descname"><span class="pre">no_outbound_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_outbound_for" title="Permalink to this definition">#</a></dt>
<dd><dl class="field-list simple"> <dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt> <dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>The time in seconds since last outbound packet on the link.</p> <dd class="field-odd"><p>The time in seconds since last outbound packet on the link. This includes keepalive packets.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Link.no_data_for">
<span class="sig-name descname"><span class="pre">no_data_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_data_for" title="Permalink to this definition">#</a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>The time in seconds since payload data traversed the link. This excludes keepalive packets.</p>
</dd> </dd>
</dl> </dl>
</dd></dl> </dd></dl>
@@ -1151,7 +1161,7 @@ statistics, you will be able to retrieve stats such as <em>RSSI</em>, <em>SNR</e
<span class="sig-name descname"><span class="pre">inactive_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.inactive_for" title="Permalink to this definition">#</a></dt> <span class="sig-name descname"><span class="pre">inactive_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.inactive_for" title="Permalink to this definition">#</a></dt>
<dd><dl class="field-list simple"> <dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt> <dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>The time in seconds since activity on the link.</p> <dd class="field-odd"><p>The time in seconds since activity on the link. This includes keepalive packets.</p>
</dd> </dd>
</dl> </dl>
</dd></dl> </dd></dl>
@@ -1992,6 +2002,7 @@ will announce it.</p>
<li><a class="reference internal" href="#RNS.Link.get_establishment_rate"><code class="docutils literal notranslate"><span class="pre">get_establishment_rate()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.get_establishment_rate"><code class="docutils literal notranslate"><span class="pre">get_establishment_rate()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.no_inbound_for"><code class="docutils literal notranslate"><span class="pre">no_inbound_for()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.no_inbound_for"><code class="docutils literal notranslate"><span class="pre">no_inbound_for()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.no_outbound_for"><code class="docutils literal notranslate"><span class="pre">no_outbound_for()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.no_outbound_for"><code class="docutils literal notranslate"><span class="pre">no_outbound_for()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.no_data_for"><code class="docutils literal notranslate"><span class="pre">no_data_for()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.inactive_for"><code class="docutils literal notranslate"><span class="pre">inactive_for()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.inactive_for"><code class="docutils literal notranslate"><span class="pre">inactive_for()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.get_remote_identity"><code class="docutils literal notranslate"><span class="pre">get_remote_identity()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.get_remote_identity"><code class="docutils literal notranslate"><span class="pre">get_remote_identity()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.teardown"><code class="docutils literal notranslate"><span class="pre">teardown()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.teardown"><code class="docutils literal notranslate"><span class="pre">teardown()</span></code></a></li>
@@ -2078,7 +2089,7 @@ will announce it.</p>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
View File
@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/> <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="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="#" />
<meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/><title>Search - Reticulum Network Stack 0.6.4 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/><title>Search - Reticulum Network Stack 0.7.2 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@@ -138,7 +138,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -164,7 +164,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="#" role="search"> </a><form class="sidebar-search-container" method="get" action="#" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -262,7 +262,7 @@
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
File diff suppressed because one or more lines are too long
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Support Reticulum - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Support Reticulum - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -330,7 +330,7 @@ report issues, suggest functionality and contribute code to Reticulum.</p>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Understanding Reticulum - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Understanding Reticulum - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -1196,7 +1196,7 @@ those risks are acceptable to you.</p>
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.6.4 beta documentation</title> <title>Using Reticulum on Your System - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -1057,7 +1057,7 @@ systemctl --user enable rnsd.service
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+4 -4
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" /> <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-7.1.2, furo 2022.09.29.dev1"/> <meta name="generator" content="sphinx-7.1.2, furo 2022.09.29.dev1"/>
<title>What is Reticulum? - Reticulum Network Stack 0.6.4 beta documentation</title> <title>What is Reticulum? - Reticulum Network Stack 0.7.2 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=a746c00c" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" /> <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=189ec851f9bb375a2509b67be1f64f0cf212b702" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" /> <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
@@ -141,7 +141,7 @@
</label> </label>
</div> </div>
<div class="header-center"> <div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.6.4 beta documentation</div></a> <a href="index.html"><div class="brand">Reticulum Network Stack 0.7.2 beta documentation</div></a>
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="theme-toggle-container theme-toggle-header"> <div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/> <img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div> </div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.6.4 beta documentation</span> <span class="sidebar-brand-text">Reticulum Network Stack 0.7.2 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search"> </a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search"> <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
@@ -434,7 +434,7 @@ want to help out with this, or can help sponsor an audit, please do get in touch
</aside> </aside>
</div> </div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=d9f3c795"></script> </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js?v=50521ac4"></script>
<script src="_static/doctools.js?v=888ff710"></script> <script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=4825356b"></script> <script src="_static/sphinx_highlight.js?v=4825356b"></script>
<script src="_static/scripts/furo.js?v=2c7c1115"></script> <script src="_static/scripts/furo.js?v=2c7c1115"></script>
+29 -4
View File
@@ -140,6 +140,7 @@ class TestLink(unittest.TestCase):
pstart = time.time() pstart = time.time()
print("Sending "+str(num_packets)+" link packets of "+str(packet_size)+" bytes...") print("Sending "+str(num_packets)+" link packets of "+str(packet_size)+" bytes...")
for i in range(0, num_packets): for i in range(0, num_packets):
time.sleep(0.003)
b += packet_size b += packet_size
data = os.urandom(packet_size) data = os.urandom(packet_size)
start = time.time() start = time.time()
@@ -188,6 +189,9 @@ class TestLink(unittest.TestCase):
id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0])) id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0]))
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1])) self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
RNS.Transport.request_path(bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
time.sleep(0.2)
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish") dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d")) self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
@@ -203,6 +207,7 @@ class TestLink(unittest.TestCase):
resource = RNS.Resource(data, l1, timeout=resource_timeout) resource = RNS.Resource(data, l1, timeout=resource_timeout)
start = time.time() start = time.time()
# This is a hack, don't do it. Use the callbacks instead.
while resource.status < RNS.Resource.COMPLETE: while resource.status < RNS.Resource.COMPLETE:
time.sleep(0.01) time.sleep(0.01)
@@ -224,6 +229,9 @@ class TestLink(unittest.TestCase):
id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0])) id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0]))
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1])) self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
RNS.Transport.request_path(bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
time.sleep(0.2)
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish") dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d")) self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
@@ -239,6 +247,7 @@ class TestLink(unittest.TestCase):
resource = RNS.Resource(data, l1, timeout=resource_timeout) resource = RNS.Resource(data, l1, timeout=resource_timeout)
start = time.time() start = time.time()
# This is a hack, don't do it. Use the callbacks instead.
while resource.status < RNS.Resource.COMPLETE: while resource.status < RNS.Resource.COMPLETE:
time.sleep(0.01) time.sleep(0.01)
@@ -260,6 +269,9 @@ class TestLink(unittest.TestCase):
id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0])) id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0]))
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1])) self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
RNS.Transport.request_path(bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
time.sleep(0.2)
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish") dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d")) self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
@@ -274,6 +286,7 @@ class TestLink(unittest.TestCase):
resource = RNS.Resource(data, l1, timeout=resource_timeout) resource = RNS.Resource(data, l1, timeout=resource_timeout)
start = time.time() start = time.time()
# This is a hack, don't do it. Use the callbacks instead.
while resource.status < RNS.Resource.COMPLETE: while resource.status < RNS.Resource.COMPLETE:
time.sleep(0.01) time.sleep(0.01)
@@ -300,6 +313,9 @@ class TestLink(unittest.TestCase):
id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0])) id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0]))
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1])) self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
RNS.Transport.request_path(bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
time.sleep(0.2)
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish") dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d")) self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
@@ -314,6 +330,7 @@ class TestLink(unittest.TestCase):
resource = RNS.Resource(data, l1, timeout=resource_timeout) resource = RNS.Resource(data, l1, timeout=resource_timeout)
start = time.time() start = time.time()
# This is a hack, don't do it. Use the callbacks instead.
while resource.status < RNS.Resource.COMPLETE: while resource.status < RNS.Resource.COMPLETE:
time.sleep(0.01) time.sleep(0.01)
@@ -325,6 +342,10 @@ class TestLink(unittest.TestCase):
time.sleep(0.5) time.sleep(0.5)
self.assertEqual(l1.status, RNS.Link.CLOSED) self.assertEqual(l1.status, RNS.Link.CLOSED)
large_resource_status = None
def lr_callback(self, resource):
TestLink.large_resource_status = resource.status
@skipIf(os.getenv('SKIP_NORMAL_TESTS') != None, "Skipping") @skipIf(os.getenv('SKIP_NORMAL_TESTS') != None, "Skipping")
def test_9_large_resource(self): def test_9_large_resource(self):
if RNS.Cryptography.backend() == "internal": if RNS.Cryptography.backend() == "internal":
@@ -339,6 +360,9 @@ class TestLink(unittest.TestCase):
id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0])) id1 = RNS.Identity.from_bytes(bytes.fromhex(fixed_keys[0][0]))
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1])) self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
RNS.Transport.request_path(bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
time.sleep(0.2)
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish") dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d")) self.assertEqual(dest.hash, bytes.fromhex("fb48da0e82e6e01ba0c014513f74540d"))
@@ -347,17 +371,18 @@ class TestLink(unittest.TestCase):
self.assertEqual(l1.status, RNS.Link.ACTIVE) self.assertEqual(l1.status, RNS.Link.ACTIVE)
resource_timeout = 120 resource_timeout = 120
resource_size = 35*1000*1000 resource_size = 50*1000*1000
data = os.urandom(resource_size) data = os.urandom(resource_size)
print("Sending "+self.size_str(resource_size)+" resource...") print("Sending "+self.size_str(resource_size)+" resource...")
resource = RNS.Resource(data, l1, timeout=resource_timeout) resource = RNS.Resource(data, l1, timeout=resource_timeout, callback=self.lr_callback)
start = time.time() start = time.time()
while resource.status < RNS.Resource.COMPLETE: TestLink.large_resource_status = resource.status
while TestLink.large_resource_status < RNS.Resource.COMPLETE:
time.sleep(0.01) time.sleep(0.01)
t = time.time() - start t = time.time() - start
self.assertEqual(resource.status, RNS.Resource.COMPLETE) self.assertEqual(TestLink.large_resource_status, RNS.Resource.COMPLETE)
print("Resource completed at "+self.size_str(resource_size/t, "b")+"ps") print("Resource completed at "+self.size_str(resource_size/t, "b")+"ps")
l1.teardown() l1.teardown()