mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-26 15:30:18 +00:00
Added custom interfaces to documentation and readme
This commit is contained in:
parent
36c761e8dd
commit
890846fa8d
@ -53,7 +53,10 @@ For more info, see [reticulum.network](https://reticulum.network/) and [the FAQ
|
|||||||
- HMAC using SHA256 for authentication
|
- HMAC using SHA256 for authentication
|
||||||
- IVs are generated through os.urandom()
|
- IVs are generated through os.urandom()
|
||||||
- Unforgeable packet delivery confirmations
|
- Unforgeable packet delivery confirmations
|
||||||
- A large variety of supported interface types
|
- Flexible and extensible interface system
|
||||||
|
- Includes a large variety of built-in interface types
|
||||||
|
- Ability to load and utilise custom user- or community-supplied interface types
|
||||||
|
- Easily create your own custom interfaces for communicating over anything
|
||||||
- An intuitive and easy-to-use API
|
- An intuitive and easy-to-use API
|
||||||
- Reliable and efficient transfer of arbitrary amounts of data
|
- Reliable and efficient transfer of arbitrary amounts of data
|
||||||
- Reticulum can handle a few bytes of data or files of many gigabytes
|
- Reticulum can handle a few bytes of data or files of many gigabytes
|
||||||
|
@ -126,3 +126,17 @@ interface to efficiently pass files of any size over a Reticulum :ref:`Link<api-
|
|||||||
.. literalinclude:: ../../Examples/Filetransfer.py
|
.. literalinclude:: ../../Examples/Filetransfer.py
|
||||||
|
|
||||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py>`_.
|
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py>`_.
|
||||||
|
|
||||||
|
.. _example-custominterface:
|
||||||
|
|
||||||
|
Custom Interfaces
|
||||||
|
=================
|
||||||
|
|
||||||
|
The *ExampleInterface* demonstrates creating custom interfaces for Reticulum.
|
||||||
|
Any number of custom interfaces can be loaded and utilised by Reticulum, and
|
||||||
|
will be fully on-par with natively included interfaces, including all supported
|
||||||
|
:ref:`interface modes<interfaces-modes>` and :ref:`common configuration options<interfaces-options>`.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../Examples/ExampleInterface.py
|
||||||
|
|
||||||
|
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/ExampleInterface.py>`_.
|
@ -14,6 +14,11 @@ for Reticulum to use.
|
|||||||
The following sections describe the interfaces currently available in Reticulum,
|
The following sections describe the interfaces currently available in Reticulum,
|
||||||
and gives example configurations for the respective interface types.
|
and gives example configurations for the respective interface types.
|
||||||
|
|
||||||
|
In addition to the built-in interface types, Reticulum is fully extensible with
|
||||||
|
custom, user- or community-supplied interfaces, and creating custom interface
|
||||||
|
modules is straightforward. Please see the :ref:`custom interface<example-custominterface>`
|
||||||
|
example for basic interface code to build upon.
|
||||||
|
|
||||||
For a high-level overview of how networks can be formed over different interface
|
For a high-level overview of how networks can be formed over different interface
|
||||||
types, have a look at the :ref:`Building Networks<networks-main>` chapter of this
|
types, have a look at the :ref:`Building Networks<networks-main>` chapter of this
|
||||||
manual.
|
manual.
|
||||||
@ -493,89 +498,89 @@ Multi interface can be used to configure sub-interfaces individually.
|
|||||||
# id_interval = 600
|
# id_interval = 600
|
||||||
|
|
||||||
# A subinterface
|
# A subinterface
|
||||||
[[[HIGHDATARATE]]]
|
[[[High Datarate]]]
|
||||||
# Subinterfaces can be enabled and disabled in of themselves
|
# Subinterfaces can be enabled and disabled in of themselves
|
||||||
interface_enabled = True
|
interface_enabled = True
|
||||||
|
|
||||||
# Set frequency to 2.4GHz
|
# Set frequency to 2.4GHz
|
||||||
frequency = 2400000000
|
frequency = 2400000000
|
||||||
|
|
||||||
# Set LoRa bandwidth to 1625 KHz
|
# Set LoRa bandwidth to 1625 KHz
|
||||||
bandwidth = 1625000
|
bandwidth = 1625000
|
||||||
|
|
||||||
# Set TX power to 0 dBm (0.12 mW)
|
# Set TX power to 0 dBm (0.12 mW)
|
||||||
txpower = 0
|
txpower = 0
|
||||||
|
|
||||||
# The virtual port, only the manufacturer
|
# The virtual port, only the manufacturer
|
||||||
# or the person who wrote the board config
|
# or the person who wrote the board config
|
||||||
# can tell you what it will be for which
|
# can tell you what it will be for which
|
||||||
# physical hardware interface
|
# physical hardware interface
|
||||||
vport = 1
|
vport = 1
|
||||||
|
|
||||||
# Select spreading factor 5. Valid
|
# Select spreading factor 5. Valid
|
||||||
# range is 5 through 12, with 5
|
# range is 5 through 12, with 5
|
||||||
# being the fastest and 12 having
|
# being the fastest and 12 having
|
||||||
# the longest range.
|
# the longest range.
|
||||||
spreadingfactor = 5
|
spreadingfactor = 5
|
||||||
|
|
||||||
# Select coding rate 5. Valid range
|
# Select coding rate 5. Valid range
|
||||||
# is 5 throough 8, with 5 being the
|
# is 5 throough 8, with 5 being the
|
||||||
# fastest, and 8 the longest range.
|
# fastest, and 8 the longest range.
|
||||||
codingrate = 5
|
codingrate = 5
|
||||||
|
|
||||||
# It is possible to limit the airtime
|
# It is possible to limit the airtime
|
||||||
# utilisation of an RNode by using the
|
# utilisation of an RNode by using the
|
||||||
# following two configuration options.
|
# following two configuration options.
|
||||||
# The short-term limit is applied in a
|
# The short-term limit is applied in a
|
||||||
# window of approximately 15 seconds,
|
# window of approximately 15 seconds,
|
||||||
# and the long-term limit is enforced
|
# and the long-term limit is enforced
|
||||||
# over a rolling 60 minute window. Both
|
# over a rolling 60 minute window. Both
|
||||||
# options are specified in percent.
|
# options are specified in percent.
|
||||||
|
|
||||||
# airtime_limit_long = 100
|
# airtime_limit_long = 100
|
||||||
# airtime_limit_short = 100
|
# airtime_limit_short = 100
|
||||||
|
|
||||||
[[[LOWDATARATE]]]
|
[[[Low Datarate]]]
|
||||||
# Subinterfaces can be enabled and disabled in of themselves
|
# Subinterfaces can be enabled and disabled in of themselves
|
||||||
interface_enabled = True
|
interface_enabled = True
|
||||||
|
|
||||||
# Set frequency to 865.6 MHz
|
# Set frequency to 865.6 MHz
|
||||||
frequency = 865600000
|
frequency = 865600000
|
||||||
|
|
||||||
# The virtual port, only the manufacturer
|
# The virtual port, only the manufacturer
|
||||||
# or the person who wrote the board config
|
# or the person who wrote the board config
|
||||||
# can tell you what it will be for which
|
# can tell you what it will be for which
|
||||||
# physical hardware interface
|
# physical hardware interface
|
||||||
vport = 0
|
vport = 0
|
||||||
|
|
||||||
# Set LoRa bandwidth to 125 KHz
|
# Set LoRa bandwidth to 125 KHz
|
||||||
bandwidth = 125000
|
bandwidth = 125000
|
||||||
|
|
||||||
# Set TX power to 0 dBm (0.12 mW)
|
# Set TX power to 0 dBm (0.12 mW)
|
||||||
txpower = 0
|
txpower = 0
|
||||||
|
|
||||||
# Select spreading factor 7. Valid
|
# Select spreading factor 7. Valid
|
||||||
# range is 5 through 12, with 5
|
# range is 5 through 12, with 5
|
||||||
# being the fastest and 12 having
|
# being the fastest and 12 having
|
||||||
# the longest range.
|
# the longest range.
|
||||||
spreadingfactor = 7
|
spreadingfactor = 7
|
||||||
|
|
||||||
# Select coding rate 5. Valid range
|
# Select coding rate 5. Valid range
|
||||||
# is 5 throough 8, with 5 being the
|
# is 5 throough 8, with 5 being the
|
||||||
# fastest, and 8 the longest range.
|
# fastest, and 8 the longest range.
|
||||||
codingrate = 5
|
codingrate = 5
|
||||||
|
|
||||||
# It is possible to limit the airtime
|
# It is possible to limit the airtime
|
||||||
# utilisation of an RNode by using the
|
# utilisation of an RNode by using the
|
||||||
# following two configuration options.
|
# following two configuration options.
|
||||||
# The short-term limit is applied in a
|
# The short-term limit is applied in a
|
||||||
# window of approximately 15 seconds,
|
# window of approximately 15 seconds,
|
||||||
# and the long-term limit is enforced
|
# and the long-term limit is enforced
|
||||||
# over a rolling 60 minute window. Both
|
# over a rolling 60 minute window. Both
|
||||||
# options are specified in percent.
|
# options are specified in percent.
|
||||||
|
|
||||||
# airtime_limit_long = 100
|
# airtime_limit_long = 100
|
||||||
# airtime_limit_short = 100
|
# airtime_limit_short = 100
|
||||||
|
|
||||||
.. _interfaces-serial:
|
.. _interfaces-serial:
|
||||||
|
|
||||||
|
@ -3241,6 +3241,315 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
|
|||||||
</div>
|
</div>
|
||||||
<p>This example can also be found at <a class="reference external" href="https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py">https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py</a>.</p>
|
<p>This example can also be found at <a class="reference external" href="https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py">https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py</a>.</p>
|
||||||
</section>
|
</section>
|
||||||
|
<section id="custom-interfaces">
|
||||||
|
<span id="example-custominterface"></span><h2>Custom Interfaces<a class="headerlink" href="#custom-interfaces" title="Permalink to this heading">#</a></h2>
|
||||||
|
<p>The <em>ExampleInterface</em> demonstrates creating custom interfaces for Reticulum.
|
||||||
|
Any number of custom interfaces can be loaded and utilised by Reticulum, and
|
||||||
|
will be fully on-par with natively included interfaces, including all supported
|
||||||
|
<a class="reference internal" href="interfaces.html#interfaces-modes"><span class="std std-ref">interface modes</span></a> and <a class="reference internal" href="interfaces.html#interfaces-options"><span class="std std-ref">common configuration options</span></a>.</p>
|
||||||
|
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># MIT License - Copyright (c) 2024 Mark Qvist / unsigned.io</span>
|
||||||
|
|
||||||
|
<span class="c1"># This example illustrates creating a custom interface</span>
|
||||||
|
<span class="c1"># definition, that can be loaded and used by Reticulum at</span>
|
||||||
|
<span class="c1"># runtime. Any number of custom interfaces can be created</span>
|
||||||
|
<span class="c1"># and loaded. To use the interface place it in the folder</span>
|
||||||
|
<span class="c1"># ~/.reticulum/interfaces, and add an interface entry to</span>
|
||||||
|
<span class="c1"># your Reticulum configuration file similar to this:</span>
|
||||||
|
|
||||||
|
<span class="c1"># [[Example Custom Interface]]</span>
|
||||||
|
<span class="c1"># type = ExampleInterface</span>
|
||||||
|
<span class="c1"># enabled = no</span>
|
||||||
|
<span class="c1"># mode = gateway</span>
|
||||||
|
<span class="c1"># port = /dev/ttyUSB0</span>
|
||||||
|
<span class="c1"># speed = 115200</span>
|
||||||
|
<span class="c1"># databits = 8</span>
|
||||||
|
<span class="c1"># parity = none</span>
|
||||||
|
<span class="c1"># stopbits = 1</span>
|
||||||
|
|
||||||
|
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
|
||||||
|
<span class="kn">import</span> <span class="nn">sys</span>
|
||||||
|
<span class="kn">import</span> <span class="nn">threading</span>
|
||||||
|
<span class="kn">import</span> <span class="nn">time</span>
|
||||||
|
|
||||||
|
<span class="c1"># This HDLC helper class is used by the interface</span>
|
||||||
|
<span class="c1"># to delimit and packetize data over the physical</span>
|
||||||
|
<span class="c1"># medium - in this case a serial connection.</span>
|
||||||
|
<span class="k">class</span> <span class="nc">HDLC</span><span class="p">():</span>
|
||||||
|
<span class="c1"># This example interface packetizes data using</span>
|
||||||
|
<span class="c1"># simplified HDLC framing, similar to PPP</span>
|
||||||
|
<span class="n">FLAG</span> <span class="o">=</span> <span class="mh">0x7E</span>
|
||||||
|
<span class="n">ESC</span> <span class="o">=</span> <span class="mh">0x7D</span>
|
||||||
|
<span class="n">ESC_MASK</span> <span class="o">=</span> <span class="mh">0x20</span>
|
||||||
|
|
||||||
|
<span class="nd">@staticmethod</span>
|
||||||
|
<span class="k">def</span> <span class="nf">escape</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
|
||||||
|
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="nb">bytes</span><span class="p">([</span><span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span><span class="p">]),</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span><span class="p">,</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span><span class="o">^</span><span class="n">HDLC</span><span class="o">.</span><span class="n">ESC_MASK</span><span class="p">]))</span>
|
||||||
|
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="nb">bytes</span><span class="p">([</span><span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span><span class="p">]),</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span><span class="p">,</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span><span class="o">^</span><span class="n">HDLC</span><span class="o">.</span><span class="n">ESC_MASK</span><span class="p">]))</span>
|
||||||
|
<span class="k">return</span> <span class="n">data</span>
|
||||||
|
|
||||||
|
<span class="c1"># Let's define our custom interface class. It must</span>
|
||||||
|
<span class="c1"># be a sub-class of the RNS "Interface" class.</span>
|
||||||
|
<span class="k">class</span> <span class="nc">ExampleInterface</span><span class="p">(</span><span class="n">Interface</span><span class="p">):</span>
|
||||||
|
<span class="c1"># All interface classes must define a default</span>
|
||||||
|
<span class="c1"># IFAC size, used in IFAC setup when the user</span>
|
||||||
|
<span class="c1"># has not specified a custom IFAC size. This</span>
|
||||||
|
<span class="c1"># option is specified in bytes.</span>
|
||||||
|
<span class="n">DEFAULT_IFAC_SIZE</span> <span class="o">=</span> <span class="mi">8</span>
|
||||||
|
|
||||||
|
<span class="c1"># The following properties are local to this</span>
|
||||||
|
<span class="c1"># particular interface implementation.</span>
|
||||||
|
<span class="n">owner</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="n">port</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="n">speed</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="n">databits</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="n">parity</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="n">stopbits</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="n">serial</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
|
||||||
|
<span class="c1"># All Reticulum interfaces must have an __init__</span>
|
||||||
|
<span class="c1"># method that takes 2 positional arguments:</span>
|
||||||
|
<span class="c1"># The owner RNS Transport instance, and a dict</span>
|
||||||
|
<span class="c1"># of configuration values.</span>
|
||||||
|
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">owner</span><span class="p">,</span> <span class="n">configuration</span><span class="p">):</span>
|
||||||
|
|
||||||
|
<span class="c1"># The following lines demonstrate handling</span>
|
||||||
|
<span class="c1"># potential dependencies required for the</span>
|
||||||
|
<span class="c1"># interface to function correctly.</span>
|
||||||
|
<span class="kn">import</span> <span class="nn">importlib</span>
|
||||||
|
<span class="k">if</span> <span class="n">importlib</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">find_spec</span><span class="p">(</span><span class="s1">'serial'</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="kn">import</span> <span class="nn">serial</span>
|
||||||
|
<span class="k">else</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">"Using this interface requires a serial communication module to be installed."</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_CRITICAL</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">"You can install one with the command: python3 -m pip install pyserial"</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_CRITICAL</span><span class="p">)</span>
|
||||||
|
<span class="n">RNS</span><span class="o">.</span><span class="n">panic</span><span class="p">()</span>
|
||||||
|
|
||||||
|
<span class="c1"># We start out by initialising the super-class</span>
|
||||||
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
|
||||||
|
|
||||||
|
<span class="c1"># To make sure the configuration data is in the</span>
|
||||||
|
<span class="c1"># correct format, we parse it through the following</span>
|
||||||
|
<span class="c1"># method on the generic Interface class. This step</span>
|
||||||
|
<span class="c1"># is required to ensure compatibility on all the</span>
|
||||||
|
<span class="c1"># platforms that Reticulum supports.</span>
|
||||||
|
<span class="n">ifconf</span> <span class="o">=</span> <span class="n">Interface</span><span class="o">.</span><span class="n">get_config_obj</span><span class="p">(</span><span class="n">configuration</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># Read the interface name from the configuration</span>
|
||||||
|
<span class="c1"># and set it on our interface instance.</span>
|
||||||
|
<span class="n">name</span> <span class="o">=</span> <span class="n">ifconf</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
|
||||||
|
|
||||||
|
<span class="c1"># We read configuration parameters from the supplied</span>
|
||||||
|
<span class="c1"># configuration data, and provide default values in</span>
|
||||||
|
<span class="c1"># case any are missing.</span>
|
||||||
|
<span class="n">port</span> <span class="o">=</span> <span class="n">ifconf</span><span class="p">[</span><span class="s2">"port"</span><span class="p">]</span> <span class="k">if</span> <span class="s2">"port"</span> <span class="ow">in</span> <span class="n">ifconf</span> <span class="k">else</span> <span class="kc">None</span>
|
||||||
|
<span class="n">speed</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ifconf</span><span class="p">[</span><span class="s2">"speed"</span><span class="p">])</span> <span class="k">if</span> <span class="s2">"speed"</span> <span class="ow">in</span> <span class="n">ifconf</span> <span class="k">else</span> <span class="mi">9600</span>
|
||||||
|
<span class="n">databits</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ifconf</span><span class="p">[</span><span class="s2">"databits"</span><span class="p">])</span> <span class="k">if</span> <span class="s2">"databits"</span> <span class="ow">in</span> <span class="n">ifconf</span> <span class="k">else</span> <span class="mi">8</span>
|
||||||
|
<span class="n">parity</span> <span class="o">=</span> <span class="n">ifconf</span><span class="p">[</span><span class="s2">"parity"</span><span class="p">]</span> <span class="k">if</span> <span class="s2">"parity"</span> <span class="ow">in</span> <span class="n">ifconf</span> <span class="k">else</span> <span class="s2">"N"</span>
|
||||||
|
<span class="n">stopbits</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ifconf</span><span class="p">[</span><span class="s2">"stopbits"</span><span class="p">])</span> <span class="k">if</span> <span class="s2">"stopbits"</span> <span class="ow">in</span> <span class="n">ifconf</span> <span class="k">else</span> <span class="mi">1</span>
|
||||||
|
|
||||||
|
<span class="c1"># In case no port is specified, we abort setup by</span>
|
||||||
|
<span class="c1"># raising an exception.</span>
|
||||||
|
<span class="k">if</span> <span class="n">port</span> <span class="o">==</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No port specified for </span><span class="si">{</span><span class="bp">self</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># All interfaces must supply a hardware MTU value</span>
|
||||||
|
<span class="c1"># to the RNS Transport instance. This value should</span>
|
||||||
|
<span class="c1"># be the maximum data packet payload size that the</span>
|
||||||
|
<span class="c1"># underlying medium is capable of handling in all</span>
|
||||||
|
<span class="c1"># cases without any segmentation.</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">HW_MTU</span> <span class="o">=</span> <span class="mi">564</span>
|
||||||
|
|
||||||
|
<span class="c1"># We initially set the "online" property to false,</span>
|
||||||
|
<span class="c1"># since the interface has not actually been fully</span>
|
||||||
|
<span class="c1"># initialised and connected yet.</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">online</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
|
||||||
|
<span class="c1"># In this case, we can also set the indicated bit-</span>
|
||||||
|
<span class="c1"># rate of the interface to the serial port speed.</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">bitrate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">speed</span>
|
||||||
|
|
||||||
|
<span class="c1"># Configure internal properties on the interface</span>
|
||||||
|
<span class="c1"># according to the supplied configuration.</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">pyserial</span> <span class="o">=</span> <span class="n">serial</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">serial</span> <span class="o">=</span> <span class="kc">None</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">owner</span> <span class="o">=</span> <span class="n">owner</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="n">port</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">speed</span> <span class="o">=</span> <span class="n">speed</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">databits</span> <span class="o">=</span> <span class="n">databits</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">parity</span> <span class="o">=</span> <span class="n">serial</span><span class="o">.</span><span class="n">PARITY_NONE</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">stopbits</span> <span class="o">=</span> <span class="n">stopbits</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="mi">100</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">parity</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">"e"</span> <span class="ow">or</span> <span class="n">parity</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">"even"</span><span class="p">:</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">parity</span> <span class="o">=</span> <span class="n">serial</span><span class="o">.</span><span class="n">PARITY_EVEN</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">parity</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">"o"</span> <span class="ow">or</span> <span class="n">parity</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">"odd"</span><span class="p">:</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">parity</span> <span class="o">=</span> <span class="n">serial</span><span class="o">.</span><span class="n">PARITY_ODD</span>
|
||||||
|
|
||||||
|
<span class="c1"># Since all required parameters are now configured,</span>
|
||||||
|
<span class="c1"># we will try opening the serial port.</span>
|
||||||
|
<span class="k">try</span><span class="p">:</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">open_port</span><span class="p">()</span>
|
||||||
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</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">"Could not open serial port for interface "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_ERROR</span><span class="p">)</span>
|
||||||
|
<span class="k">raise</span> <span class="n">e</span>
|
||||||
|
|
||||||
|
<span class="c1"># If opening the port succeeded, run any post-open</span>
|
||||||
|
<span class="c1"># configuration required.</span>
|
||||||
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">is_open</span><span class="p">:</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">configure_device</span><span class="p">()</span>
|
||||||
|
<span class="k">else</span><span class="p">:</span>
|
||||||
|
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s2">"Could not open serial port"</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># Open the serial port with supplied configuration</span>
|
||||||
|
<span class="c1"># parameters and store a reference to the open port.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">open_port</span><span class="p">(</span><span class="bp">self</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">"Opening serial port "</span><span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="o">+</span><span class="s2">"..."</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_VERBOSE</span><span class="p">)</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">serial</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pyserial</span><span class="o">.</span><span class="n">Serial</span><span class="p">(</span>
|
||||||
|
<span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">,</span>
|
||||||
|
<span class="n">baudrate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">speed</span><span class="p">,</span>
|
||||||
|
<span class="n">bytesize</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">databits</span><span class="p">,</span>
|
||||||
|
<span class="n">parity</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parity</span><span class="p">,</span>
|
||||||
|
<span class="n">stopbits</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stopbits</span><span class="p">,</span>
|
||||||
|
<span class="n">xonxoff</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
||||||
|
<span class="n">rtscts</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
||||||
|
<span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
|
||||||
|
<span class="n">inter_byte_timeout</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||||
|
<span class="n">write_timeout</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||||
|
<span class="n">dsrdtr</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
||||||
|
<span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># The only thing required after opening the port</span>
|
||||||
|
<span class="c1"># is to wait a small amount of time for the</span>
|
||||||
|
<span class="c1"># hardware to initialise and then start a thread</span>
|
||||||
|
<span class="c1"># that reads any incoming data from the device.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">configure_device</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||||
|
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</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="bp">self</span><span class="o">.</span><span class="n">read_loop</span><span class="p">)</span>
|
||||||
|
<span class="n">thread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span>
|
||||||
|
<span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">online</span> <span class="o">=</span> <span class="kc">True</span>
|
||||||
|
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Serial port "</span><span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="o">+</span><span class="s2">" is now open"</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_VERBOSE</span><span class="p">)</span>
|
||||||
|
|
||||||
|
|
||||||
|
<span class="c1"># This method will be called from our read-loop</span>
|
||||||
|
<span class="c1"># whenever a full packet has been received over</span>
|
||||||
|
<span class="c1"># the underlying medium.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">process_incoming</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||||
|
<span class="c1"># Update our received bytes counter</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">rxb</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># And send the data packet to the Transport</span>
|
||||||
|
<span class="c1"># instance for processing.</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="o">.</span><span class="n">inbound</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># The running Reticulum Transport instance will</span>
|
||||||
|
<span class="c1"># call this method on the interface whenever the</span>
|
||||||
|
<span class="c1"># interface must transmit a packet.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">process_outgoing</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">data</span><span class="p">):</span>
|
||||||
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">online</span><span class="p">:</span>
|
||||||
|
<span class="c1"># First, escape and packetize the data</span>
|
||||||
|
<span class="c1"># according to HDLC framing.</span>
|
||||||
|
<span class="n">data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span><span class="p">])</span><span class="o">+</span><span class="n">HDLC</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">+</span><span class="nb">bytes</span><span class="p">([</span><span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span><span class="p">])</span>
|
||||||
|
|
||||||
|
<span class="c1"># Then write the framed data to the port</span>
|
||||||
|
<span class="n">written</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># Update the transmitted bytes counter</span>
|
||||||
|
<span class="c1"># and ensure that all data was written</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">txb</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
||||||
|
<span class="k">if</span> <span class="n">written</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
|
||||||
|
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s2">"Serial interface only wrote "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">written</span><span class="p">)</span><span class="o">+</span><span class="s2">" bytes of "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>
|
||||||
|
|
||||||
|
<span class="c1"># This read loop runs in a thread and continously</span>
|
||||||
|
<span class="c1"># receives bytes from the underlying serial port.</span>
|
||||||
|
<span class="c1"># When a full packet has been received, it will</span>
|
||||||
|
<span class="c1"># be sent to the process_incoming methed, which</span>
|
||||||
|
<span class="c1"># will in turn pass it to the Transport instance.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">read_loop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||||
|
<span class="k">try</span><span class="p">:</span>
|
||||||
|
<span class="n">in_frame</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="n">escape</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="n">data_buffer</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||||
|
<span class="n">last_read_ms</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">*</span><span class="mi">1000</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">is_open</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">in_waiting</span><span class="p">:</span>
|
||||||
|
<span class="n">byte</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
|
||||||
|
<span class="n">last_read_ms</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">*</span><span class="mi">1000</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="p">(</span><span class="n">in_frame</span> <span class="ow">and</span> <span class="n">byte</span> <span class="o">==</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span><span class="p">):</span>
|
||||||
|
<span class="n">in_frame</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">process_incoming</span><span class="p">(</span><span class="n">data_buffer</span><span class="p">)</span>
|
||||||
|
<span class="k">elif</span> <span class="p">(</span><span class="n">byte</span> <span class="o">==</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span><span class="p">):</span>
|
||||||
|
<span class="n">in_frame</span> <span class="o">=</span> <span class="kc">True</span>
|
||||||
|
<span class="n">data_buffer</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||||
|
<span class="k">elif</span> <span class="p">(</span><span class="n">in_frame</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_buffer</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">HW_MTU</span><span class="p">):</span>
|
||||||
|
<span class="k">if</span> <span class="p">(</span><span class="n">byte</span> <span class="o">==</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span><span class="p">):</span>
|
||||||
|
<span class="n">escape</span> <span class="o">=</span> <span class="kc">True</span>
|
||||||
|
<span class="k">else</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="p">(</span><span class="n">escape</span><span class="p">):</span>
|
||||||
|
<span class="k">if</span> <span class="p">(</span><span class="n">byte</span> <span class="o">==</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span> <span class="o">^</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">ESC_MASK</span><span class="p">):</span>
|
||||||
|
<span class="n">byte</span> <span class="o">=</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">FLAG</span>
|
||||||
|
<span class="k">if</span> <span class="p">(</span><span class="n">byte</span> <span class="o">==</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span> <span class="o">^</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">ESC_MASK</span><span class="p">):</span>
|
||||||
|
<span class="n">byte</span> <span class="o">=</span> <span class="n">HDLC</span><span class="o">.</span><span class="n">ESC</span>
|
||||||
|
<span class="n">escape</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="n">data_buffer</span> <span class="o">=</span> <span class="n">data_buffer</span><span class="o">+</span><span class="nb">bytes</span><span class="p">([</span><span class="n">byte</span><span class="p">])</span>
|
||||||
|
|
||||||
|
<span class="k">else</span><span class="p">:</span>
|
||||||
|
<span class="n">time_since_last</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">*</span><span class="mi">1000</span><span class="p">)</span> <span class="o">-</span> <span class="n">last_read_ms</span>
|
||||||
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_buffer</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">time_since_last</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">:</span>
|
||||||
|
<span class="n">data_buffer</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||||
|
<span class="n">in_frame</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="n">escape</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.08</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">online</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"A serial port error occurred, the contained exception was: "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_ERROR</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">"The interface "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">+</span><span class="s2">" experienced an unrecoverable error and is now offline."</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_ERROR</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">panic_on_interface_error</span><span class="p">:</span>
|
||||||
|
<span class="n">RNS</span><span class="o">.</span><span class="n">panic</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">"Reticulum will attempt to reconnect the interface periodically."</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_ERROR</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">online</span> <span class="o">=</span> <span class="kc">False</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">reconnect_port</span><span class="p">()</span>
|
||||||
|
|
||||||
|
<span class="c1"># This method handles serial port disconnects.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">reconnect_port</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||||
|
<span class="k">while</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">online</span><span class="p">:</span>
|
||||||
|
<span class="k">try</span><span class="p">:</span>
|
||||||
|
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</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">"Attempting to reconnect serial port "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">)</span><span class="o">+</span><span class="s2">" for "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">+</span><span class="s2">"..."</span><span class="p">,</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_VERBOSE</span><span class="p">)</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">open_port</span><span class="p">()</span>
|
||||||
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">serial</span><span class="o">.</span><span class="n">is_open</span><span class="p">:</span>
|
||||||
|
<span class="bp">self</span><span class="o">.</span><span class="n">configure_device</span><span class="p">()</span>
|
||||||
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</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">"Error while reconnecting port, the contained exception was: "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span> <span class="n">RNS</span><span class="o">.</span><span class="n">LOG_ERROR</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">"Reconnected serial port for "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||||||
|
|
||||||
|
<span class="c1"># Signal to Reticulum that this interface should</span>
|
||||||
|
<span class="c1"># not perform any ingress limiting.</span>
|
||||||
|
<span class="k">def</span> <span class="nf">should_ingress_limit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||||
|
<span class="k">return</span> <span class="kc">False</span>
|
||||||
|
|
||||||
|
<span class="c1"># We must provide a string representation of this</span>
|
||||||
|
<span class="c1"># interface, that is used whenever the interface</span>
|
||||||
|
<span class="c1"># is printed in logs or external programs.</span>
|
||||||
|
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||||
|
<span class="k">return</span> <span class="s2">"ExampleInterface["</span><span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="o">+</span><span class="s2">"]"</span>
|
||||||
|
|
||||||
|
<span class="c1"># Finally, register the defined interface class as the</span>
|
||||||
|
<span class="c1"># target class for Reticulum to use as an interface</span>
|
||||||
|
<span class="n">interface_class</span> <span class="o">=</span> <span class="n">ExampleInterface</span>
|
||||||
|
</pre></div>
|
||||||
|
</div>
|
||||||
|
<p>This example can also be found at <a class="reference external" href="https://github.com/markqvist/Reticulum/blob/master/Examples/ExampleInterface.py">https://github.com/markqvist/Reticulum/blob/master/Examples/ExampleInterface.py</a>.</p>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
@ -3310,6 +3619,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
|
|||||||
<li><a class="reference internal" href="#channel">Channel</a></li>
|
<li><a class="reference internal" href="#channel">Channel</a></li>
|
||||||
<li><a class="reference internal" href="#buffer">Buffer</a></li>
|
<li><a class="reference internal" href="#buffer">Buffer</a></li>
|
||||||
<li><a class="reference internal" href="#filetransfer">Filetransfer</a></li>
|
<li><a class="reference internal" href="#filetransfer">Filetransfer</a></li>
|
||||||
|
<li><a class="reference internal" href="#custom-interfaces">Custom Interfaces</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -371,6 +371,7 @@ to participate in the development of Reticulum itself.</p>
|
|||||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#channel">Channel</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="examples.html#channel">Channel</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#buffer">Buffer</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="examples.html#buffer">Buffer</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#filetransfer">Filetransfer</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="examples.html#filetransfer">Filetransfer</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="examples.html#custom-interfaces">Custom Interfaces</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="support.html">Support Reticulum</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="support.html">Support Reticulum</a><ul>
|
||||||
|
@ -230,6 +230,10 @@ common to them all is that you will need to define one or more <em>interfaces</e
|
|||||||
for Reticulum to use.</p>
|
for Reticulum to use.</p>
|
||||||
<p>The following sections describe the interfaces currently available in Reticulum,
|
<p>The following sections describe the interfaces currently available in Reticulum,
|
||||||
and gives example configurations for the respective interface types.</p>
|
and gives example configurations for the respective interface types.</p>
|
||||||
|
<p>In addition to the built-in interface types, Reticulum is fully extensible with
|
||||||
|
custom, user- or community-supplied interfaces, and creating custom interface
|
||||||
|
modules is straightforward. Please see the <a class="reference internal" href="examples.html#example-custominterface"><span class="std std-ref">custom interface</span></a>
|
||||||
|
example for basic interface code to build upon.</p>
|
||||||
<p>For a high-level overview of how networks can be formed over different interface
|
<p>For a high-level overview of how networks can be formed over different interface
|
||||||
types, have a look at the <a class="reference internal" href="networks.html#networks-main"><span class="std std-ref">Building Networks</span></a> chapter of this
|
types, have a look at the <a class="reference internal" href="networks.html#networks-main"><span class="std std-ref">Building Networks</span></a> chapter of this
|
||||||
manual.</p>
|
manual.</p>
|
||||||
@ -644,89 +648,89 @@ Multi interface can be used to configure sub-interfaces individually.</p>
|
|||||||
<span class="c1"># id_interval = 600</span>
|
<span class="c1"># id_interval = 600</span>
|
||||||
|
|
||||||
<span class="c1"># A subinterface</span>
|
<span class="c1"># A subinterface</span>
|
||||||
<span class="p">[[[</span><span class="n">HIGHDATARATE</span><span class="p">]]]</span>
|
<span class="p">[[[</span><span class="n">High</span> <span class="n">Datarate</span><span class="p">]]]</span>
|
||||||
<span class="c1"># Subinterfaces can be enabled and disabled in of themselves</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="n">interface_enabled</span> <span class="o">=</span> <span class="kc">True</span>
|
||||||
|
|
||||||
<span class="c1"># Set frequency to 2.4GHz</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="n">frequency</span> <span class="o">=</span> <span class="mi">2400000000</span>
|
||||||
|
|
||||||
<span class="c1"># Set LoRa bandwidth to 1625 KHz</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="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="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="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"># The virtual port, only the manufacturer</span>
|
||||||
<span class="c1"># or the person who wrote the board config</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"># can tell you what it will be for which</span>
|
||||||
<span class="c1"># physical hardware interface</span>
|
<span class="c1"># physical hardware interface</span>
|
||||||
<span class="n">vport</span> <span class="o">=</span> <span class="mi">1</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"># Select spreading factor 5. Valid</span>
|
||||||
<span class="c1"># range is 5 through 12, with 5</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"># being the fastest and 12 having</span>
|
||||||
<span class="c1"># the longest range.</span>
|
<span class="c1"># the longest range.</span>
|
||||||
<span class="n">spreadingfactor</span> <span class="o">=</span> <span class="mi">5</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"># Select coding rate 5. Valid range</span>
|
||||||
<span class="c1"># is 5 throough 8, with 5 being the</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="c1"># fastest, and 8 the longest range.</span>
|
||||||
<span class="n">codingrate</span> <span class="o">=</span> <span class="mi">5</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"># It is possible to limit the airtime</span>
|
||||||
<span class="c1"># utilisation of an RNode by using the</span>
|
<span class="c1"># utilisation of an RNode by using the</span>
|
||||||
<span class="c1"># following two configuration options.</span>
|
<span class="c1"># following two configuration options.</span>
|
||||||
<span class="c1"># The short-term limit is applied in a</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"># window of approximately 15 seconds,</span>
|
||||||
<span class="c1"># and the long-term limit is enforced</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"># over a rolling 60 minute window. Both</span>
|
||||||
<span class="c1"># options are specified in percent.</span>
|
<span class="c1"># options are specified in percent.</span>
|
||||||
|
|
||||||
<span class="c1"># airtime_limit_long = 100</span>
|
<span class="c1"># airtime_limit_long = 100</span>
|
||||||
<span class="c1"># airtime_limit_short = 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="p">[[[</span><span class="n">Low</span> <span class="n">Datarate</span><span class="p">]]]</span>
|
||||||
<span class="c1"># Subinterfaces can be enabled and disabled in of themselves</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="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="c1"># Set frequency to 865.6 MHz</span>
|
||||||
<span class="n">frequency</span> <span class="o">=</span> <span class="mi">865600000</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"># The virtual port, only the manufacturer</span>
|
||||||
<span class="c1"># or the person who wrote the board config</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"># can tell you what it will be for which</span>
|
||||||
<span class="c1"># physical hardware interface</span>
|
<span class="c1"># physical hardware interface</span>
|
||||||
<span class="n">vport</span> <span class="o">=</span> <span class="mi">0</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="c1"># Set LoRa bandwidth to 125 KHz</span>
|
||||||
<span class="n">bandwidth</span> <span class="o">=</span> <span class="mi">125000</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="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="n">txpower</span> <span class="o">=</span> <span class="mi">0</span>
|
||||||
|
|
||||||
<span class="c1"># Select spreading factor 7. Valid</span>
|
<span class="c1"># Select spreading factor 7. Valid</span>
|
||||||
<span class="c1"># range is 5 through 12, with 5</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"># being the fastest and 12 having</span>
|
||||||
<span class="c1"># the longest range.</span>
|
<span class="c1"># the longest range.</span>
|
||||||
<span class="n">spreadingfactor</span> <span class="o">=</span> <span class="mi">7</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"># Select coding rate 5. Valid range</span>
|
||||||
<span class="c1"># is 5 throough 8, with 5 being the</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="c1"># fastest, and 8 the longest range.</span>
|
||||||
<span class="n">codingrate</span> <span class="o">=</span> <span class="mi">5</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"># It is possible to limit the airtime</span>
|
||||||
<span class="c1"># utilisation of an RNode by using the</span>
|
<span class="c1"># utilisation of an RNode by using the</span>
|
||||||
<span class="c1"># following two configuration options.</span>
|
<span class="c1"># following two configuration options.</span>
|
||||||
<span class="c1"># The short-term limit is applied in a</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"># window of approximately 15 seconds,</span>
|
||||||
<span class="c1"># and the long-term limit is enforced</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"># over a rolling 60 minute window. Both</span>
|
||||||
<span class="c1"># options are specified in percent.</span>
|
<span class="c1"># options are specified in percent.</span>
|
||||||
|
|
||||||
<span class="c1"># airtime_limit_long = 100</span>
|
<span class="c1"># airtime_limit_long = 100</span>
|
||||||
<span class="c1"># airtime_limit_short = 100</span>
|
<span class="c1"># airtime_limit_short = 100</span>
|
||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -126,3 +126,17 @@ interface to efficiently pass files of any size over a Reticulum :ref:`Link<api-
|
|||||||
.. literalinclude:: ../../Examples/Filetransfer.py
|
.. literalinclude:: ../../Examples/Filetransfer.py
|
||||||
|
|
||||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py>`_.
|
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py>`_.
|
||||||
|
|
||||||
|
.. _example-custominterface:
|
||||||
|
|
||||||
|
Custom Interfaces
|
||||||
|
=================
|
||||||
|
|
||||||
|
The *ExampleInterface* demonstrates creating custom interfaces for Reticulum.
|
||||||
|
Any number of custom interfaces can be loaded and utilised by Reticulum, and
|
||||||
|
will be fully on-par with natively included interfaces, including all supported
|
||||||
|
:ref:`interface modes<interfaces-modes>` and :ref:`common configuration options<interfaces-options>`.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../Examples/ExampleInterface.py
|
||||||
|
|
||||||
|
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/ExampleInterface.py>`_.
|
@ -14,6 +14,11 @@ for Reticulum to use.
|
|||||||
The following sections describe the interfaces currently available in Reticulum,
|
The following sections describe the interfaces currently available in Reticulum,
|
||||||
and gives example configurations for the respective interface types.
|
and gives example configurations for the respective interface types.
|
||||||
|
|
||||||
|
In addition to the built-in interface types, Reticulum is fully extensible with
|
||||||
|
custom, user- or community-supplied interfaces, and creating custom interface
|
||||||
|
modules is straightforward. Please see the :ref:`custom interface<example-custominterface>`
|
||||||
|
example for basic interface code to build upon.
|
||||||
|
|
||||||
For a high-level overview of how networks can be formed over different interface
|
For a high-level overview of how networks can be formed over different interface
|
||||||
types, have a look at the :ref:`Building Networks<networks-main>` chapter of this
|
types, have a look at the :ref:`Building Networks<networks-main>` chapter of this
|
||||||
manual.
|
manual.
|
||||||
|
Loading…
Reference in New Issue
Block a user