Compare commits

..

9 Commits

Author SHA1 Message Date
Mark Qvist
bce37fe8c0 Fixed rnstatus JSON output bug when IFAC was enabled on an interface 2024-08-28 23:25:18 +02:00
Mark Qvist
0c95d720db Improved rncp progress status display 2024-08-28 21:34:16 +02:00
Mark Qvist
96527380c3 Improved rncp progress status display 2024-08-28 21:21:38 +02:00
Mark Qvist
035a44e34d Fixed invalid resource progress reported in some cases 2024-08-28 21:21:09 +02:00
Mark Qvist
59bb09426c Updated documentation 2024-08-28 20:37:19 +02:00
Mark Qvist
6ac07989b0 Added link age to link API 2024-08-28 20:36:51 +02:00
Mark Qvist
f1d6cda337 Added RNodeMultiInterface to documentation 2024-08-28 18:47:33 +02:00
Mark Qvist
4aa60243a7 Merge branch 'master' of github.com:markqvist/Reticulum 2024-08-28 18:27:01 +02:00
Mark Qvist
849bd1bdad Fixed typo 2024-08-28 16:54:31 +02:00
18 changed files with 415 additions and 27 deletions

View File

@ -462,6 +462,15 @@ class Link:
def get_context(self): def get_context(self):
return None return None
def get_age(self):
"""
:returns: The time in seconds since this link was established.
"""
if self.activated_at:
return time.time() - self.activated_at
else:
return None
def no_inbound_for(self): def no_inbound_for(self):
""" """
:returns: The time in seconds since last inbound packet on the link. This includes keepalive packets. :returns: The time in seconds since last inbound packet on the link. This includes keepalive packets.

View File

@ -923,7 +923,9 @@ class Resource:
""" """
:returns: The current progress of the resource transfer as a *float* between 0.0 and 1.0. :returns: The current progress of the resource transfer as a *float* between 0.0 and 1.0.
""" """
if self.initiator: if self.status == RNS.Resource.COMPLETE and self.segment_index == self.total_segments:
return 1.0
elif self.initiator:
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU) self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
self.processed_parts += self.sent_parts self.processed_parts += self.sent_parts
self.progress_total_parts = float(self.grand_total_parts) self.progress_total_parts = float(self.grand_total_parts)

View File

@ -477,7 +477,10 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
prg = current_resource.get_progress() prg = current_resource.get_progress()
percent = round(prg * 100.0, 1) percent = round(prg * 100.0, 1)
stat_str = str(percent)+"% - " + size_str(int(prg*current_resource.total_size)) + " of " + size_str(current_resource.total_size) + " - " +size_str(speed, "b")+"ps" stat_str = str(percent)+"% - " + size_str(int(prg*current_resource.total_size)) + " of " + size_str(current_resource.total_size) + " - " +size_str(speed, "b")+"ps"
print("\r \rTransferring file "+syms[i]+" "+stat_str, end=" ") if prg != 1.0:
print("\r \rTransferring file "+syms[i]+" "+stat_str, end=" ")
else:
print("\r \rTransfer complete "+stat_str, end=" ")
else: else:
print("\r \rWaiting for transfer to start "+syms[i]+" ", end=" ") print("\r \rWaiting for transfer to start "+syms[i]+" ", end=" ")
sys.stdout.flush() sys.stdout.flush()
@ -491,9 +494,10 @@ def fetch(configdir, verbosity = 0, quietness = 0, destination = None, file = No
exit(1) exit(1)
else: else:
if silent: if silent:
print(str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash)) print(str(file)+" fetched from "+RNS.prettyhexrep(destination_hash))
else: else:
print("\r \r"+str(file)+" fetched from "+RNS.prettyhexrep(destination_hash)) #print("\r \r"+str(file)+" fetched from "+RNS.prettyhexrep(destination_hash))
print("\n"+str(file)+" fetched from "+RNS.prettyhexrep(destination_hash))
link.teardown() link.teardown()
time.sleep(0.15) time.sleep(0.15)
exit(0) exit(0)
@ -648,15 +652,25 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
else: else:
print("\r \rTransferring file ", end=" ") print("\r \rTransferring file ", end=" ")
def progress_update(i, done=False):
time.sleep(0.1)
prg = current_resource.get_progress()
percent = round(prg * 100.0, 1)
stat_str = str(percent)+"% - " + size_str(int(prg*current_resource.total_size)) + " of " + size_str(current_resource.total_size) + " - " +size_str(speed, "b")+"ps"
if not done:
print("\r \rTransferring file "+syms[i]+" "+stat_str, end=" ")
else:
print("\r \rTransfer complete "+stat_str, end=" ")
sys.stdout.flush()
i = (i+1)%len(syms)
return i
while not resource_done: while not resource_done:
if not silent: if not silent:
time.sleep(0.1) i = progress_update(i)
prg = current_resource.get_progress()
percent = round(prg * 100.0, 1) if not silent:
stat_str = str(percent)+"% - " + size_str(int(prg*current_resource.total_size)) + " of " + size_str(current_resource.total_size) + " - " +size_str(speed, "b")+"ps" i = progress_update(i, done=True)
print("\r \rTransferring file "+syms[i]+" "+stat_str, end=" ")
sys.stdout.flush()
i = (i+1)%len(syms)
if current_resource.status != RNS.Resource.COMPLETE: if current_resource.status != RNS.Resource.COMPLETE:
if silent: if silent:
@ -668,7 +682,8 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if silent: if silent:
print(str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash)) print(str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
else: else:
print("\r \r"+str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash)) # print("\r \r"+str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
print("\n"+str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
link.teardown() link.teardown()
time.sleep(0.25) time.sleep(0.25)
real_file.close() real_file.close()

View File

@ -69,7 +69,7 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
if isinstance(stats[s], bytes): if isinstance(stats[s], bytes):
stats[s] = RNS.hexrep(stats[s], delimit=False) stats[s] = RNS.hexrep(stats[s], delimit=False)
if isinstance(stats[s], dict): if isinstance(stats[s], dict) or isinstance(stats[s], list):
for i in stats[s]: for i in stats[s]:
if isinstance(i, dict): if isinstance(i, dict):
for k in i: for k in i:

View File

@ -406,6 +406,121 @@ can be used, and offers full control over LoRa parameters.
# airtime_limit_short = 33 # airtime_limit_short = 33
.. _interfaces-rnode-multi:
RNode Multi Interface
=====================
For RNodes that support multiple LoRa transceivers, the RNode
Multi interface can be used to configure sub-interfaces individually.
.. code::
# Here's an example of how to add an RNode Multi interface
# using the RNode LoRa transceiver.
[[RNode Multi Interface]]
type = RNodeMultiInterface
# Enable interface if you want to use it!
interface_enabled = True
# Serial port for the device
port = /dev/ttyACM0
# You can configure the RNode to send
# out identification on the channel with
# a set interval by configuring the
# following two parameters.
# id_callsign = MYCALL-0
# id_interval = 600
# A subinterface
[[[HIGHDATARATE]]]
# Subinterfaces can be enabled and disabled in of themselves
interface_enabled = True
# Set frequency to 2.4GHz
frequency = 2400000000
# Set LoRa bandwidth to 1625 KHz
bandwidth = 1625000
# Set TX power to 0 dBm (0.12 mW)
txpower = 0
# The virtual port, only the manufacturer
# or the person who wrote the board config
# can tell you what it will be for which
# physical hardware interface
vport = 1
# Select spreading factor 5. Valid
# range is 5 through 12, with 5
# being the fastest and 12 having
# the longest range.
spreadingfactor = 5
# Select coding rate 5. Valid range
# is 5 throough 8, with 5 being the
# fastest, and 8 the longest range.
codingrate = 5
# It is possible to limit the airtime
# utilisation of an RNode by using the
# following two configuration options.
# The short-term limit is applied in a
# window of approximately 15 seconds,
# and the long-term limit is enforced
# over a rolling 60 minute window. Both
# options are specified in percent.
# airtime_limit_long = 100
# airtime_limit_short = 100
[[[LOWDATARATE]]]
# Subinterfaces can be enabled and disabled in of themselves
interface_enabled = True
# Set frequency to 865.6 MHz
frequency = 865600000
# The virtual port, only the manufacturer
# or the person who wrote the board config
# can tell you what it will be for which
# physical hardware interface
vport = 0
# Set LoRa bandwidth to 125 KHz
bandwidth = 125000
# Set TX power to 0 dBm (0.12 mW)
txpower = 0
# Select spreading factor 7. Valid
# range is 5 through 12, with 5
# being the fastest and 12 having
# the longest range.
spreadingfactor = 7
# Select coding rate 5. Valid range
# is 5 throough 8, with 5 being the
# fastest, and 8 the longest range.
codingrate = 5
# It is possible to limit the airtime
# utilisation of an RNode by using the
# following two configuration options.
# The short-term limit is applied in a
# window of approximately 15 seconds,
# and the long-term limit is enforced
# over a rolling 60 minute window. Both
# options are specified in percent.
# airtime_limit_long = 100
# airtime_limit_short = 100
.. _interfaces-serial: .. _interfaces-serial:
Serial Interface Serial Interface

View File

@ -60,7 +60,7 @@ with Reticulum:
* | Reticulum is designed to work reliably in open, trustless environments. This * | Reticulum is designed to work reliably in open, trustless environments. This
means you can use it to create open-access networks, where participants can means you can use it to create open-access networks, where participants can
join and leave in an free and unorganised manner. This property allows an join and leave in a free and unorganised manner. This property allows an
entirely new, and so far, mostly unexplored class of networked applications, entirely new, and so far, mostly unexplored class of networked applications,
where networks, and the information flow within them can form and dissolve where networks, and the information flow within them can form and dissolve
organically. organically.

View File

@ -106,17 +106,17 @@ body[data-theme="dark"] .highlight .cp { color: #ff3a3a; font-weight: bold } /*
body[data-theme="dark"] .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ body[data-theme="dark"] .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */
body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */
body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
body[data-theme="dark"] .highlight .gd { color: #d22323 } /* Generic.Deleted */ body[data-theme="dark"] .highlight .gd { color: #ff3a3a } /* Generic.Deleted */
body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
body[data-theme="dark"] .highlight .gr { color: #d22323 } /* Generic.Error */ body[data-theme="dark"] .highlight .gr { color: #ff3a3a } /* Generic.Error */
body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */ body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */
body[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */ body[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */
body[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ body[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
body[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ body[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
body[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ body[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
body[data-theme="dark"] .highlight .gt { color: #d22323 } /* Generic.Traceback */ body[data-theme="dark"] .highlight .gt { color: #ff3a3a } /* Generic.Traceback */
body[data-theme="dark"] .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ body[data-theme="dark"] .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */
body[data-theme="dark"] .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ body[data-theme="dark"] .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */
body[data-theme="dark"] .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ body[data-theme="dark"] .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */
@ -192,17 +192,17 @@ body:not([data-theme="light"]) .highlight .cp { color: #ff3a3a; font-weight: bol
body:not([data-theme="light"]) .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ body:not([data-theme="light"]) .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */
body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */
body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
body:not([data-theme="light"]) .highlight .gd { color: #d22323 } /* Generic.Deleted */ body:not([data-theme="light"]) .highlight .gd { color: #ff3a3a } /* Generic.Deleted */
body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
body:not([data-theme="light"]) .highlight .gr { color: #d22323 } /* Generic.Error */ body:not([data-theme="light"]) .highlight .gr { color: #ff3a3a } /* Generic.Error */
body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */ body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */
body:not([data-theme="light"]) .highlight .go { color: #cccccc } /* Generic.Output */ body:not([data-theme="light"]) .highlight .go { color: #cccccc } /* Generic.Output */
body:not([data-theme="light"]) .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ body:not([data-theme="light"]) .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
body:not([data-theme="light"]) .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ body:not([data-theme="light"]) .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
body:not([data-theme="light"]) .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ body:not([data-theme="light"]) .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
body:not([data-theme="light"]) .highlight .gt { color: #d22323 } /* Generic.Traceback */ body:not([data-theme="light"]) .highlight .gt { color: #ff3a3a } /* Generic.Traceback */
body:not([data-theme="light"]) .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ body:not([data-theme="light"]) .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */
body:not([data-theme="light"]) .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ body:not([data-theme="light"]) .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */
body:not([data-theme="light"]) .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ body:not([data-theme="light"]) .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */

View File

@ -1072,7 +1072,7 @@ destination, and passing traffic back and forth over the link.</p>
<span class="s2">&quot; running, waiting for a connection.&quot;</span> <span class="s2">&quot; running, waiting for a connection.&quot;</span>
<span class="p">)</span> <span class="p">)</span>
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">&quot;Hit enter to manually send an announce (Ctrl-C to quit)&quot;</span><span class="p">)</span> <span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">&quot;Hit enter to manually send an announce (Ctrl-C or </span><span class="se">\&quot;</span><span class="s2">quit</span><span class="se">\&quot;</span><span class="s2"> to quit)&quot;</span><span class="p">)</span>
<span class="c1"># We enter a loop that runs until the users exits.</span> <span class="c1"># We enter a loop that runs until the users exits.</span>
<span class="c1"># If the user hits enter, we will announce our server</span> <span class="c1"># If the user hits enter, we will announce our server</span>
@ -1082,6 +1082,12 @@ destination, and passing traffic back and forth over the link.</p>
<span class="n">entered</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span> <span class="n">entered</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
<span class="n">destination</span><span class="o">.</span><span class="n">announce</span><span class="p">()</span> <span class="n">destination</span><span class="o">.</span><span class="n">announce</span><span class="p">()</span>
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">&quot;Sent announce from &quot;</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">destination</span><span class="o">.</span><span class="n">hash</span><span class="p">))</span> <span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">&quot;Sent announce from &quot;</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">destination</span><span class="o">.</span><span class="n">hash</span><span class="p">))</span>
<span class="k">if</span> <span class="n">entered</span> <span class="o">==</span> <span class="s2">&quot;quit&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="n">latest_client_link</span><span class="p">:</span>
<span class="n">latest_client_link</span><span class="o">.</span><span class="n">teardown</span><span class="p">()</span>
<span class="k">break</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">exit</span><span class="p">()</span>
<span class="c1"># When a client establishes a link to our server</span> <span class="c1"># When a client establishes a link to our server</span>
<span class="c1"># destination, this function will be called with</span> <span class="c1"># destination, this function will be called with</span>

View File

@ -366,6 +366,8 @@
<h2>G</h2> <h2>G</h2>
<table style="width: 100%" class="indextable genindextable"><tr> <table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Link.get_age">get_age() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.Link.get_channel">get_channel() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.get_channel">get_channel() (RNS.Link method)</a>
</li> </li>
<li><a href="reference.html#RNS.Resource.get_data_size">get_data_size() (RNS.Resource method)</a> <li><a href="reference.html#RNS.Resource.get_data_size">get_data_size() (RNS.Resource method)</a>
@ -391,11 +393,11 @@
</li> </li>
</ul></li> </ul></li>
<li><a href="reference.html#RNS.Identity.get_public_key">get_public_key() (RNS.Identity method)</a> <li><a href="reference.html#RNS.Identity.get_public_key">get_public_key() (RNS.Identity method)</a>
</li>
<li><a href="reference.html#RNS.Link.get_q">get_q() (RNS.Link method)</a>
</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.get_q">get_q() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.Identity.get_random_hash">get_random_hash() (RNS.Identity static method)</a> <li><a href="reference.html#RNS.Identity.get_random_hash">get_random_hash() (RNS.Identity static method)</a>
</li> </li>
<li><a href="reference.html#RNS.Link.get_remote_identity">get_remote_identity() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.get_remote_identity">get_remote_identity() (RNS.Link method)</a>

View File

@ -409,7 +409,7 @@ by adding one of the following interfaces to your <code class="docutils literal
<span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">BetweenTheBorders</span><span class="p">]]</span> <span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">BetweenTheBorders</span><span class="p">]]</span>
<span class="nb">type</span> <span class="o">=</span> <span class="n">TCPClientInterface</span> <span class="nb">type</span> <span class="o">=</span> <span class="n">TCPClientInterface</span>
<span class="n">enabled</span> <span class="o">=</span> <span class="n">yes</span> <span class="n">enabled</span> <span class="o">=</span> <span class="n">yes</span>
<span class="n">target_host</span> <span class="o">=</span> <span class="n">betweentheborders</span><span class="o">.</span><span class="n">com</span> <span class="n">target_host</span> <span class="o">=</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">betweentheborders</span><span class="o">.</span><span class="n">com</span>
<span class="n">target_port</span> <span class="o">=</span> <span class="mi">4242</span> <span class="n">target_port</span> <span class="o">=</span> <span class="mi">4242</span>
<span class="c1"># Interface to Testnet I2P Hub</span> <span class="c1"># Interface to Testnet I2P Hub</span>

View File

@ -338,6 +338,7 @@ to participate in the development of Reticulum itself.</p>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#tcp-client-interface">TCP Client Interface</a></li> <li class="toctree-l2"><a class="reference internal" href="interfaces.html#tcp-client-interface">TCP Client Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#udp-interface">UDP Interface</a></li> <li class="toctree-l2"><a class="reference internal" href="interfaces.html#udp-interface">UDP Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#rnode-lora-interface">RNode LoRa Interface</a></li> <li class="toctree-l2"><a class="reference internal" href="interfaces.html#rnode-lora-interface">RNode LoRa Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#rnode-multi-interface">RNode Multi Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#serial-interface">Serial Interface</a></li> <li class="toctree-l2"><a class="reference internal" href="interfaces.html#serial-interface">Serial Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#pipe-interface">Pipe Interface</a></li> <li class="toctree-l2"><a class="reference internal" href="interfaces.html#pipe-interface">Pipe Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="interfaces.html#kiss-interface">KISS Interface</a></li> <li class="toctree-l2"><a class="reference internal" href="interfaces.html#kiss-interface">KISS Interface</a></li>

View File

@ -569,6 +569,117 @@ can be used, and offers full control over LoRa parameters.</p>
</pre></div> </pre></div>
</div> </div>
</section> </section>
<section id="rnode-multi-interface">
<span id="interfaces-rnode-multi"></span><h2>RNode Multi Interface<a class="headerlink" href="#rnode-multi-interface" title="Permalink to this heading">#</a></h2>
<p>For RNodes that support multiple LoRa transceivers, the RNode
Multi interface can be used to configure sub-interfaces individually.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Here&#39;s an example of how to add an RNode Multi interface</span>
<span class="c1"># using the RNode LoRa transceiver.</span>
<span class="p">[[</span><span class="n">RNode</span> <span class="n">Multi</span> <span class="n">Interface</span><span class="p">]]</span>
<span class="nb">type</span> <span class="o">=</span> <span class="n">RNodeMultiInterface</span>
<span class="c1"># Enable interface if you want to use it!</span>
<span class="n">interface_enabled</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># Serial port for the device</span>
<span class="n">port</span> <span class="o">=</span> <span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">ttyACM0</span>
<span class="c1"># You can configure the RNode to send</span>
<span class="c1"># out identification on the channel with</span>
<span class="c1"># a set interval by configuring the</span>
<span class="c1"># following two parameters.</span>
<span class="c1"># id_callsign = MYCALL-0</span>
<span class="c1"># id_interval = 600</span>
<span class="c1"># A subinterface</span>
<span class="p">[[[</span><span class="n">HIGHDATARATE</span><span class="p">]]]</span>
<span class="c1"># Subinterfaces can be enabled and disabled in of themselves</span>
<span class="n">interface_enabled</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># Set frequency to 2.4GHz</span>
<span class="n">frequency</span> <span class="o">=</span> <span class="mi">2400000000</span>
<span class="c1"># Set LoRa bandwidth to 1625 KHz</span>
<span class="n">bandwidth</span> <span class="o">=</span> <span class="mi">1625000</span>
<span class="c1"># Set TX power to 0 dBm (0.12 mW)</span>
<span class="n">txpower</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># The virtual port, only the manufacturer</span>
<span class="c1"># or the person who wrote the board config</span>
<span class="c1"># can tell you what it will be for which</span>
<span class="c1"># physical hardware interface</span>
<span class="n">vport</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c1"># Select spreading factor 5. Valid</span>
<span class="c1"># range is 5 through 12, with 5</span>
<span class="c1"># being the fastest and 12 having</span>
<span class="c1"># the longest range.</span>
<span class="n">spreadingfactor</span> <span class="o">=</span> <span class="mi">5</span>
<span class="c1"># Select coding rate 5. Valid range</span>
<span class="c1"># is 5 throough 8, with 5 being the</span>
<span class="c1"># fastest, and 8 the longest range.</span>
<span class="n">codingrate</span> <span class="o">=</span> <span class="mi">5</span>
<span class="c1"># It is possible to limit the airtime</span>
<span class="c1"># utilisation of an RNode by using the</span>
<span class="c1"># following two configuration options.</span>
<span class="c1"># The short-term limit is applied in a</span>
<span class="c1"># window of approximately 15 seconds,</span>
<span class="c1"># and the long-term limit is enforced</span>
<span class="c1"># over a rolling 60 minute window. Both</span>
<span class="c1"># options are specified in percent.</span>
<span class="c1"># airtime_limit_long = 100</span>
<span class="c1"># airtime_limit_short = 100</span>
<span class="p">[[[</span><span class="n">LOWDATARATE</span><span class="p">]]]</span>
<span class="c1"># Subinterfaces can be enabled and disabled in of themselves</span>
<span class="n">interface_enabled</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># Set frequency to 865.6 MHz</span>
<span class="n">frequency</span> <span class="o">=</span> <span class="mi">865600000</span>
<span class="c1"># The virtual port, only the manufacturer</span>
<span class="c1"># or the person who wrote the board config</span>
<span class="c1"># can tell you what it will be for which</span>
<span class="c1"># physical hardware interface</span>
<span class="n">vport</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Set LoRa bandwidth to 125 KHz</span>
<span class="n">bandwidth</span> <span class="o">=</span> <span class="mi">125000</span>
<span class="c1"># Set TX power to 0 dBm (0.12 mW)</span>
<span class="n">txpower</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Select spreading factor 7. Valid</span>
<span class="c1"># range is 5 through 12, with 5</span>
<span class="c1"># being the fastest and 12 having</span>
<span class="c1"># the longest range.</span>
<span class="n">spreadingfactor</span> <span class="o">=</span> <span class="mi">7</span>
<span class="c1"># Select coding rate 5. Valid range</span>
<span class="c1"># is 5 throough 8, with 5 being the</span>
<span class="c1"># fastest, and 8 the longest range.</span>
<span class="n">codingrate</span> <span class="o">=</span> <span class="mi">5</span>
<span class="c1"># It is possible to limit the airtime</span>
<span class="c1"># utilisation of an RNode by using the</span>
<span class="c1"># following two configuration options.</span>
<span class="c1"># The short-term limit is applied in a</span>
<span class="c1"># window of approximately 15 seconds,</span>
<span class="c1"># and the long-term limit is enforced</span>
<span class="c1"># over a rolling 60 minute window. Both</span>
<span class="c1"># options are specified in percent.</span>
<span class="c1"># airtime_limit_long = 100</span>
<span class="c1"># airtime_limit_short = 100</span>
</pre></div>
</div>
</section>
<section id="serial-interface"> <section id="serial-interface">
<span id="interfaces-serial"></span><h2>Serial Interface<a class="headerlink" href="#serial-interface" title="Permalink to this heading">#</a></h2> <span id="interfaces-serial"></span><h2>Serial Interface<a class="headerlink" href="#serial-interface" title="Permalink to this heading">#</a></h2>
<p>Reticulum can be used over serial ports directly, or over any device with a <p>Reticulum can be used over serial ports directly, or over any device with a
@ -1104,6 +1215,7 @@ to <code class="docutils literal notranslate"><span class="pre">30</span></code>
<li><a class="reference internal" href="#tcp-client-interface">TCP Client Interface</a></li> <li><a class="reference internal" href="#tcp-client-interface">TCP Client Interface</a></li>
<li><a class="reference internal" href="#udp-interface">UDP Interface</a></li> <li><a class="reference internal" href="#udp-interface">UDP Interface</a></li>
<li><a class="reference internal" href="#rnode-lora-interface">RNode LoRa Interface</a></li> <li><a class="reference internal" href="#rnode-lora-interface">RNode LoRa Interface</a></li>
<li><a class="reference internal" href="#rnode-multi-interface">RNode Multi Interface</a></li>
<li><a class="reference internal" href="#serial-interface">Serial Interface</a></li> <li><a class="reference internal" href="#serial-interface">Serial Interface</a></li>
<li><a class="reference internal" href="#pipe-interface">Pipe Interface</a></li> <li><a class="reference internal" href="#pipe-interface">Pipe Interface</a></li>
<li><a class="reference internal" href="#kiss-interface">KISS Interface</a></li> <li><a class="reference internal" href="#kiss-interface">KISS Interface</a></li>

View File

@ -294,7 +294,7 @@ than that.</em></p>
<li><div class="line-block"> <li><div class="line-block">
<div class="line">Reticulum is designed to work reliably in open, trustless environments. This <div class="line">Reticulum is designed to work reliably in open, trustless environments. This
means you can use it to create open-access networks, where participants can means you can use it to create open-access networks, where participants can
join and leave in an free and unorganised manner. This property allows an join and leave in a free and unorganised manner. This property allows an
entirely new, and so far, mostly unexplored class of networked applications, entirely new, and so far, mostly unexplored class of networked applications,
where networks, and the information flow within them can form and dissolve where networks, and the information flow within them can form and dissolve
organically.</div> organically.</div>

Binary file not shown.

View File

@ -1126,6 +1126,16 @@ statistics, you will be able to retrieve stats such as <em>RSSI</em>, <em>SNR</e
</dl> </dl>
</dd></dl> </dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Link.get_age">
<span class="sig-name descname"><span class="pre">get_age</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.get_age" 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 this link was established.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Link.no_inbound_for"> <dt class="sig sig-object py" id="RNS.Link.no_inbound_for">
<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>
@ -2000,6 +2010,7 @@ will announce it.</p>
<li><a class="reference internal" href="#RNS.Link.get_snr"><code class="docutils literal notranslate"><span class="pre">get_snr()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.get_snr"><code class="docutils literal notranslate"><span class="pre">get_snr()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.get_q"><code class="docutils literal notranslate"><span class="pre">get_q()</span></code></a></li> <li><a class="reference internal" href="#RNS.Link.get_q"><code class="docutils literal notranslate"><span class="pre">get_q()</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.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_age"><code class="docutils literal notranslate"><span class="pre">get_age()</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.no_data_for"><code class="docutils literal notranslate"><span class="pre">no_data_for()</span></code></a></li>

File diff suppressed because one or more lines are too long

View File

@ -406,6 +406,121 @@ can be used, and offers full control over LoRa parameters.
# airtime_limit_short = 33 # airtime_limit_short = 33
.. _interfaces-rnode-multi:
RNode Multi Interface
=====================
For RNodes that support multiple LoRa transceivers, the RNode
Multi interface can be used to configure sub-interfaces individually.
.. code::
# Here's an example of how to add an RNode Multi interface
# using the RNode LoRa transceiver.
[[RNode Multi Interface]]
type = RNodeMultiInterface
# Enable interface if you want to use it!
interface_enabled = True
# Serial port for the device
port = /dev/ttyACM0
# You can configure the RNode to send
# out identification on the channel with
# a set interval by configuring the
# following two parameters.
# id_callsign = MYCALL-0
# id_interval = 600
# A subinterface
[[[HIGHDATARATE]]]
# Subinterfaces can be enabled and disabled in of themselves
interface_enabled = True
# Set frequency to 2.4GHz
frequency = 2400000000
# Set LoRa bandwidth to 1625 KHz
bandwidth = 1625000
# Set TX power to 0 dBm (0.12 mW)
txpower = 0
# The virtual port, only the manufacturer
# or the person who wrote the board config
# can tell you what it will be for which
# physical hardware interface
vport = 1
# Select spreading factor 5. Valid
# range is 5 through 12, with 5
# being the fastest and 12 having
# the longest range.
spreadingfactor = 5
# Select coding rate 5. Valid range
# is 5 throough 8, with 5 being the
# fastest, and 8 the longest range.
codingrate = 5
# It is possible to limit the airtime
# utilisation of an RNode by using the
# following two configuration options.
# The short-term limit is applied in a
# window of approximately 15 seconds,
# and the long-term limit is enforced
# over a rolling 60 minute window. Both
# options are specified in percent.
# airtime_limit_long = 100
# airtime_limit_short = 100
[[[LOWDATARATE]]]
# Subinterfaces can be enabled and disabled in of themselves
interface_enabled = True
# Set frequency to 865.6 MHz
frequency = 865600000
# The virtual port, only the manufacturer
# or the person who wrote the board config
# can tell you what it will be for which
# physical hardware interface
vport = 0
# Set LoRa bandwidth to 125 KHz
bandwidth = 125000
# Set TX power to 0 dBm (0.12 mW)
txpower = 0
# Select spreading factor 7. Valid
# range is 5 through 12, with 5
# being the fastest and 12 having
# the longest range.
spreadingfactor = 7
# Select coding rate 5. Valid range
# is 5 throough 8, with 5 being the
# fastest, and 8 the longest range.
codingrate = 5
# It is possible to limit the airtime
# utilisation of an RNode by using the
# following two configuration options.
# The short-term limit is applied in a
# window of approximately 15 seconds,
# and the long-term limit is enforced
# over a rolling 60 minute window. Both
# options are specified in percent.
# airtime_limit_long = 100
# airtime_limit_short = 100
.. _interfaces-serial: .. _interfaces-serial:
Serial Interface Serial Interface

View File

@ -60,7 +60,7 @@ with Reticulum:
* | Reticulum is designed to work reliably in open, trustless environments. This * | Reticulum is designed to work reliably in open, trustless environments. This
means you can use it to create open-access networks, where participants can means you can use it to create open-access networks, where participants can
join and leave in an free and unorganised manner. This property allows an join and leave in a free and unorganised manner. This property allows an
entirely new, and so far, mostly unexplored class of networked applications, entirely new, and so far, mostly unexplored class of networked applications,
where networks, and the information flow within them can form and dissolve where networks, and the information flow within them can form and dissolve
organically. organically.