build manpage

This commit is contained in:
John Goerzen 2020-09-26 17:41:38 -05:00
parent ff9c58d140
commit 529043530c

View File

@ -1,215 +1,173 @@
.\" Automatically generated by Pandoc 2.2.1
.\"
.TH "LORAPIPE" "1" "October 2019" "John Goerzen" "lorapipe Manual"
.TH "XBNET" "1" "October 2019" "John Goerzen" "xbnet Manual"
.hy
.SH NAME
.PP
lorapipe \- Transfer data and run a network over LoRa long\-range radios
xbnet \- Transfer data and run a network over XBee long\-range radios
.SH SYNOPSIS
.PP
\f[B]lorapipe\f[] [ \f[I]OPTIONS\f[] ] \f[B]PORT\f[] \f[B]COMMAND\f[] [
\f[B]xbnet\f[] [ \f[I]OPTIONS\f[] ] \f[B]PORT\f[] \f[B]COMMAND\f[] [
\f[I]command_options\f[] ]
.SH OVERVIEW
.PP
\f[B]lorapipe\f[] is designed to integrate LoRa long\-range radios into
a Unix/Linux system.
In particular, lorapipe can:
\f[B]xbnet\f[] is designed to integrate XBee long\-range radios into a
Unix/Linux system.
In particular, xbnet can:
.IP \[bu] 2
Bidirectionally pipe data across a LoRa radio system
Bidirectionally pipe data across a XBee radio system
.IP \[bu] 2
Do an RF ping and report signal strength at each end
Do an RF ping
.IP \[bu] 2
Operate an AX.25 network using LoRa, and atop it, TCP/IP
Operate as a virtual Ethernet device or a virtual tunnel device
.RS 2
.IP \[bu] 2
Run TCP/IP (IPv4 and IPv6) atop either of these.
.RE
.SH HARDWARE REQUIREMENTS
.PP
\f[B]lorapipe\f[] is designed to run with a Microchip RN2903/RN2483 as
implemented by LoStik.
\f[B]xbnet\f[] is designed to run with a Digi XBee device.
It is tested with the SX devices but should work with any.
.PP
Drivers for other hardware may be added in the future.
.PP
The Microchip firmware must be upgraded to 1.0.5 before running with
\f[B]lorapipe\f[].
Previous versions lacked the \f[C]radio\ rxstop\f[] command, which is a
severe limitation when receiving multiple packets rapidly.
.PP
See the documents tab for the
RN2093 (https://www.microchip.com/wwwproducts/en/RN2903) and the
firmware upgrade
guide (https://www.pocketmagic.net/rn2483-rn2903-firmware-upgrade-guide/)
\- note that the upgrade part is really finicky and you need the
\[lq]offset\[rq] file.
.SH PROTOCOL
.PP
The \f[B]lorapipe pipe\f[] command is the primary one of interest here.
It will receive data on stdin, break it up into LoRa\-sized packets (see
\f[B]\[en]maxpacketsize\f[]), and transmit it across the radio.
It also will receive data from the radio channel and send it to stdout.
No attempt at encryption or authentication is made; all packets
successfully decoded will be sent to stdout.
Authentication and filtering is left to other layers of the stack atop
\f[B]lorapipe\f[].
XBee frames are smaller than typical Ethernet or TCP frames.
XBee frames, in fact, are typically limited to about 255 bytes on the SX
series; other devices may have different limits.
Therefore, xbnet supports fragmentation and reassembly.
It will split a frame to be transmitted into the size supported by XBee,
and reassemble on the other end.
.PP
A thin layer atop \f[B]lorapipe pipe\f[] is \f[B]lorapipe kiss\f[],
which implements the AX.25 KISS protocol.
It transmits each KISS frame it receives as a LoRa frame, and
vice\-versa.
It performs rudimentary checking to ensure it is receiving valid KISS
data, and will not pass anything else to stdout.
This support can be used to build a TCP/IP network atop LoRa as will be
shown below.
Encryption and authentication could be added atop this by using tools
such as OpenVPN or SSH.
XBee, of course, cannot guarantee that all frames will be received, and
therefore xbnet can't make that guarantee either.
However, the protocols you may run atop it \[en] from UUCP to ZModem to
TCP/IP \[en] should handle this.
.PP
\f[B]lorapipe\f[] provides only the guarantees that LoRa itself does:
that raw LoRa frames which are decoded are intact, but not all frames
will be received.
It is somewhat akin to UDP in this sense.
Protocols such as UUCP, ZModem, or TCP can be layered atop
\f[B]lorapipe\f[] to transform this into a \[lq]reliable\[rq]
connection.
.SS Broadcast Use and Separate Frequencies
When running in \f[B]xbnet tap\f[] mode, it is simulating an Ethernet
interface.
Every Ethernet packet has a source and destination MAC address.
xbnet will maintain a cache of the Ethernet MAC addresses it has seen
and what XBee MAC address they came from.
Therefore, when it sees a request to transmit to a certain Ethernet MAC,
it will reuse what it knows from its cache and direct the packet to the
appropriate XBee destination.
Ethernet broadcasts are converted into XBee broadcasts.
.PP
It is quite possible to use \f[B]lorapipe\f[] to broadcast data to
multiple listeners; an unlimited number of systems can run \f[B]lorapipe
pipe\f[] to receive data, and as long as there is nothing on stdin, they
will happily decode data received over the air without transmitting
anything.
.PP
Separate communication channels may be easily achieved by selecting
separate radio frequencies.
.SS Collision Mitigation
.PP
\f[B]lorapipe\f[] cannot provide collision detection or avoidance,
though it does impliement a collision mitigation strategy as described
below.
.PP
As LoRa radios are half\-duplex (they cannot receive while
transmitting), this poses challenges for quite a few applications that
expect full\-duplex communication or something like it.
In testing, a particular problem was observed with protocols that use
transmission windows and send data in packets.
These protocols send ACKs after a successful packet transmission, which
frequently collided with the next packet transmitted from the other
radio.
This caused serious performance degredations, and for some protocols,
complete failure.
.PP
There is no carrier detect signal from the LoRa radio.
Therefore, a turn\-based mechanism is implemented; with each frame
transmitted, a byte is prepended indicating whether the sender has more
data in queue to transmit or not.
The sender will continue transmitting until its transmit buffer is
empty.
When that condition is reached, the other end will begin transmitting
whatever is in its queue.
This enables protocols such as UUCP \[lq]g\[rq] and UUCP \[lq]i\[rq] to
work quite well.
.PP
A potential complication could arise if the \[lq]last\[rq] packet from
the transmitter never arrives at the receiver; the receiver might
therefore never take a turn to transmit.
To guard against this possibility, there is a timer, and after receiving
no packets for a certain amount of time, the receiver will assume it is
acceptable to transmit.
This timeout is set by the \f[B]\[en]eotwait\f[] option and defaults to
1000ms (1 second).
.PP
The signal about whether or not data remains in the queue takes the form
of a single byte prepended to every frame.
It is 0x00 if no data will follow immediately, and 0x01 if data exists
in the transmitters queue which will be sent immediately.
The receiving side processes this byte and strips it off before handing
the data to the application.
This byte is, however, visible under \f[B]\[en]debug\f[] mode, so you
can observe the protocol at this low level.
The \f[B]xbnet tun\f[] mode operates in a similar fashion; it keeps a
cache of seen IP addresses and their corresponding XBee MAC addresses,
and directs packets appropriately.
.SH RADIO PARAMETERS AND INITIALIZATION
.PP
The Microchip command reference, available at
<http://ww1.microchip.com/downloads/en/DeviceDoc/40001811A.pdf>,
describes the parameters available for the radio.
A LoRa data rate calculator is available at
<https://www.rfwireless-world.com/calculators/LoRa-Data-Rate-Calculator.html>
to give you a rough sense of the speed of different parameters.
In general, by sacrificing speed, you can increase range and robustness
of the signal.
The default initialization uses fairly slow and high\-range settings:
.IP
.nf
\f[C]
sys\ get\ ver
mac\ reset
mac\ pause
radio\ get\ mod
radio\ get\ freq
radio\ get\ pwr
radio\ get\ sf
radio\ get\ bw
radio\ get\ cr
radio\ get\ wdt
radio\ set\ pwr\ 20
radio\ set\ sf\ sf12
radio\ set\ bw\ 125
radio\ set\ cr\ 4/5
radio\ set\ wdt\ 60000
\f[]
.fi
.PP
The \f[C]get\f[] commands will cause the pre\-initialization settings to
be output to stderr if \f[C]\-\-debug\f[] is used.
A maximum speed init would look like this:
.IP
.nf
\f[C]
sys\ get\ ver
mac\ reset
mac\ pause
radio\ get\ mod
radio\ get\ freq
radio\ get\ pwr
radio\ get\ sf
radio\ get\ bw
radio\ get\ cr
radio\ get\ wdt
radio\ set\ pwr\ 20
radio\ set\ sf\ sf7
radio\ set\ bw\ 500
radio\ set\ cr\ 4/5
radio\ set\ wdt\ 60000
\f[]
.fi
.PP
You can craft your own parameters and pass them in with
\f[C]\-\-initfile\f[] to customize the performance of your RF link.
.PP
A particular hint: if \f[C]\-\-debug\f[] shows \f[C]radio_err\f[] after
a \f[C]radio\ rx\ 0\f[] command, the radio is seeing carrier but is
getting CRC errors decoding packets.
Increasing the code rate with \f[C]radio\ set\ cr\f[] to a higher value
such as \f[C]4/6\f[] or even \f[C]4/8\f[] will increase the FEC
redundancy and enable it to decode some of those packets.
Increasing code rate will not help if there is complete silence from the
radio during a transmission; for those situations, try decreasing
bandwidth or increasing the spreading factor.
Note that coderate \f[C]4/5\f[] to the radio is the same as \f[C]1\f[]
to the calculator, while \f[C]4/8\f[] is the same as \f[C]4\f[].
.SH PROTOCOL HINTS
.PP
Although \f[B]lorapipe pipe\f[] doesn't guarantee it preserves
application framing, in many cases it does.
For applications that have their own framing, it is highly desirable to
set their frame size to be less than the \f[B]lorapipe \&... pipe
\[en]maxpacketsize\f[] setting.
This will reduce the amount of data that would have to be retransmitted
due to lost frames.
.PP
As speed decreases, packet size should as well.
This program requires API mode from the board.
It will perform that initialization automatically.
Additional configurations may be added by you using the
\f[B]\[en]initfile\f[] option.
.SH APPLICATION HINTS
.SS FULL TCP/IP USING TUN
.PP
This is the marquee feature of xbnet.
It provides a full TCP/IP stack across the XBee links, supporting both
IPv4 and IPv6.
You can do anything you wish with the participating nodes in your mesh:
ping, ssh, route the Internet across them, etc.
Up to you! A Raspberry Pi with wifi and xbnet could provide an Internet
gateway for an entire XBee mesh, if you so desire.
.PP
This works by creating a virtual network device in Linux, called a
\[lq]tun\[rq] device.
Traffic going out that device will be routed onto XBee, and traffic
coming in will be routed to the computer.
.PP
To make this work, you will first bring up the interface with xbnet.
Then, give it an IP address with ifconfig or ipaddr.
Do the same on the remote end, and boom, you can ping!
.PP
Note that for this mode, xbnet must be run as root (or granted
\f[C]CAP_NET_ADMIN\f[]).
.PP
Here's an example.
Start on machine A:
.IP
.nf
\f[C]
sudo\ xbnet\ /dev/ttyUSB3\ tun
\f[]
.fi
.PP
Wait until it tells you what interface it created.
By default, this will be \f[B]xbnet0\f[].
Now run:
.IP
.nf
\f[C]
sudo\ ip\ addr\ add\ 192.168.3.3/24\ dev\ xbnet0
sudo\ ip\ link\ set\ dev\ xbnet0\ up
\f[]
.fi
.PP
If you don't have the \f[B]ip\f[] program, you can use the older\-style
\f[B]ifconfig\f[] instead.
This one command does the same as the two newer\-style ones above:
.IP
.nf
\f[C]
sudo\ ifconfig\ xbnet0\ 192.168.3.3\ netmask\ 255.255.255.0\
\f[]
.fi
.PP
Now, on machine B, start xbnet the same as on machine A.
Give it a different IP
.IP
.nf
\f[C]
sudo\ ip\ addr\ add\ 192.168.3.4/24\ dev\ xbnet0
sudo\ ip\ link\ set\ dev\ xbnet0\ up
\f[]
.fi
.PP
Now you can ping from A to B:
.IP
.nf
\f[C]
ping\ 192.168.3.4
PING\ 192.168.3.4\ (192.168.3.4)\ 56(84)\ bytes\ of\ data.
64\ bytes\ from\ 192.168.3.4:\ icmp_seq=1\ ttl=64\ time=130\ ms
64\ bytes\ from\ 192.168.3.4:\ icmp_seq=2\ ttl=64\ time=89.1\ ms
64\ bytes\ from\ 192.168.3.4:\ icmp_seq=3\ ttl=64\ time=81.6\ ms
\f[]
.fi
.PP
For more details, see the tun command below.
.SS ETHERNET MODE WITH TAP
.PP
The tap mode is similar to the tun mode, except it simulates a full
Ethernet connection.
You might want this if you need to run a non\-IP protocol, or if you
want to do something like bridge two Ethernet segments.
The configuration is very similar.
.PP
Be aware that a lot of programs generate broadcasts across an Ethernet
interface, and bridging will do even more.
It would be easy to overwhelm your XBee network with this kind of cruft,
so the tun mode is recommended unless you have a specific need for tap.
.SS TRANSPARENT MODE
.PP
XBee systems have a \[lq]transparent mode\[rq] in which you can
configure a particular destination and use them as a raw serial port.
You should definitely consider if this meets your needs for
serial\-based protocols; it would eliminate xbnet from the path
entirely.
.PP
However, you may still wish to use xbnet; perhaps for its debugging.
Also there are some scenarios (such at TCP/IP with multiple
destinations) that really cannot be done in transparent mode \[en] and
that is what xbnet is for, and where it shines.
.SS SOCAT
.PP
The \f[B]socat\f[](1) program can be particularly helpful; it can
gateway TCP ports and various other sorts of things into
\f[B]lorapipe\f[].
This is helpful if the \f[B]lorapipe\f[] system is across a network from
gateway TCP ports and various other sorts of things into \f[B]xbnet\f[].
This is helpful if the \f[B]xbnet\f[] system is across a network from
the system you wish to run an application on.
\f[B]ssh\f[](1) can also be useful for this purpose.
.PP
@ -217,7 +175,7 @@ A basic command might be like this:
.IP
.nf
\f[C]
socat\ TCP\-LISTEN:12345\ EXEC:\[aq]lorapipe\ /dev/ttyUSB0\ pipe\[aq]
socat\ TCP\-LISTEN:12345\ EXEC:\[aq]xbnet\ /dev/ttyUSB0\ pipe\ \-\-dest=1234,pty,rawer\[aq]
\f[]
.fi
.PP
@ -227,7 +185,7 @@ In those instances, something like this may be in order:
.IP
.nf
\f[C]
socat\ TCP\-LISTEN:10104\ EXEC:\[aq]stdbuf\ \-i0\ \-o0\ \-e0\ lorapipe\ /dev/ttyUSB4\ pipe,pty,rawer\[aq]
socat\ TCP\-LISTEN:10104\ EXEC:\[aq]stdbuf\ \-i0\ \-o0\ \-e0\ xbnet\ /dev/ttyUSB4\ pipe\ \-\-dest=1234,pty,rawer\[aq]
\f[]
.fi
.SS UUCP
@ -235,8 +193,7 @@ socat\ TCP\-LISTEN:10104\ EXEC:\[aq]stdbuf\ \-i0\ \-o0\ \-e0\ lorapipe\ /dev/tty
For UUCP, I recommend protocol \f[C]i\f[] with the default window\-size
setting.
Use as large of a packet size as you can; for slow links, perhaps 32, up
to around 100 for fast, high\-quality links.
(LoRa seems to not do well with packets above 100 bytes).
to around 244 for fast, high\-quality links.
.PP
Protocol \f[C]g\f[] (or \f[C]G\f[] with a smaller packet size) can also
work, but won't work as well.
@ -255,8 +212,9 @@ chat\-timeout\ 60
\f[]
.fi
.PP
Note that UUCP protocol i adds 10 bytes of overhead per packet, so this
is designed to work with the default recommended packet size of 100.
Note that UUCP protocol i adds 10 bytes of overhead per packet and xbnet
adds 1 byte of overhead, so this is designed to work with the default
recommended packet size of 255.
.PP
Then in \f[C]/etc/uucp/port\f[]:
.IP
@ -268,15 +226,17 @@ reliable\ false
.fi
.SS YMODEM (and generic example of bidirectional pipe)
.PP
ZModem makes a poor fit for LoRa because its smallest block size is 1K.
YModem, however, uses a 128\-byte block size.
ZModem makes a good fit for the higher bitrate XBee modules.
For the slower settings, consider YModem; its 128\-byte block size may
be more suitable for very slow links than ZModem's 1K.
.PP
Here's an example of how to make it work.
Let's say we want to transmit /bin/true over the radio.
We could run this:
.IP
.nf
\f[C]
socat\ EXEC:\[aq]sz\ \-\-ymodem\ /bin/true\[aq]\ EXEC:\[aq]lorapipe\ /dev/ttyUSB0\ pipe\[aq]
socat\ EXEC:\[aq]sz\ \-\-ymodem\ /bin/true\[aq]\ EXEC:\[aq]xbnet\ /dev/ttyUSB0\ pipe\ \-\-dest=1234,pty,rawer\[aq]
\f[]
.fi
.PP
@ -284,7 +244,7 @@ And on the receiving end:
.IP
.nf
\f[C]
socat\ EXEC:\[aq]rz\ \-\-ymodem\[aq]\ EXEC:\[aq]lorapipe\ /dev/ttyUSB0\ pipe\[aq]
socat\ EXEC:\[aq]rz\ \-\-ymodem\[aq]\ EXEC:\[aq]xbnet\ /dev/ttyUSB0\ pipe\ \-\-dest=5678,pty,rawer\[aq]
\f[]
.fi
.PP
@ -293,12 +253,10 @@ For instance, \f[C]uucico\ \-l\f[] for UUCP logins.
.SS KERMIT
.PP
Using the C\-kermit distribution (\f[B]apt\-get install ckermit\f[]),
you can configure for \f[B]lorapipe\f[] like this:
you can configure for \f[B]xbnet\f[] like this:
.IP
.nf
\f[C]
set\ receive\ packet\-length\ 90
set\ send\ packet\-length\ 90
set\ duplex\ half
set\ window\ 2
set\ receive\ timeout\ 10
@ -310,7 +268,7 @@ Then, on one side, run:
.IP
.nf
\f[C]
pipe\ lorapipe\ /dev/ttyUSB0\ pipe
pipe\ xbnet\ /dev/ttyUSB0\ pipe\ \-\-dest=1234
Ctrl\-\\\ c
server
\f[]
@ -320,7 +278,7 @@ And on the other:
.IP
.nf
\f[C]
pipe\ lorapipe\ /dev/ttyUSB0\ pipe
pipe\ xbnet\ /dev/ttyUSB0\ pipe\ \-\-dest=5678
Ctrl\-\\\ c
\f[]
.fi
@ -333,18 +291,139 @@ To interact directly with the modem, something like this will work:
.IP
.nf
\f[C]
cu\ \-h\ \-\-line\ /dev/ttyUSB0\ \-s\ 57600\ \-e\ \-o\ \-f\ \-\-nostop
cu\ \-h\ \-\-line\ /dev/ttyUSB0\ \-s\ 9600\ \-e\ \-o\ \ \-\-nostop
\f[]
.fi
.SH RUNNING TCP/IP OVER XBEE WITH PPP
.PP
PPP is the fastest way to run TCP/IP over XBee with \f[B]xbnet\f[] if
you only need to have two nodes talk to each other.
PPP can work in transparent mode without xbnet as well.
It is subject to a few limitations:
.IP \[bu] 2
PPP cannot support ad\-hoc communication to multiple devices.
It is strictly point\-to\-point between two devices.
.IP \[bu] 2
PPP compression should not be turned on.
This is because PPP normally assumes a lossless connection, and any
dropped packets become rather expensive for PPP to handle, since
compression has to be re\-set.
Better to use compression at the protocol level; for instance, with
\f[B]ssh \-C\f[].
.PP
To set up PPP, on one device, create /etc/ppp/peers/xbee with this
content:
.IP
.nf
\f[C]
hide\-password\
noauth
debug
nodefaultroute
192.168.2.3:192.168.2.2\
mru\ 1024
passive
115200
nobsdcomp
nodeflate
\f[]
.fi
.PP
On the other device, swap the order of those IP addresses.
.PP
Now, fire it up on each end with a command like this:
.IP
.nf
\f[C]
socat\ EXEC:\[aq]pppd\ nodetach\ file\ /etc/ppp/peers/lora,pty,rawer\[aq]\ \\
\ \ EXEC:\[aq]xbnet\ \-\-initfile=init\-fast.txt\ /dev/ttyUSB0\ pipe\ \-\-dest=1234,pty,rawer\[aq]
\f[]
.fi
.PP
According to the PPP docs, an MRU of 296 might be suitable for slower
links.
.PP
This will now permit you to ping across the link.
Additional options can be added to add, for instance, a bit of
authentication at the start and so forth (though note that XBee, being
RF, means that a session could be hijacked, so don't put a lot of stock
in this as a limit; best to add firewall rules, etc.)
.PP
Of course, ssh can nicely run over this, but for more versatility,
consider the tap or tun options.
.SH PERFORMANCE TUNING
.PP
Here are some tips to improve performance:
.SS DISABLING XBEE ACKS
.PP
By default, the XBee system requests an acknowledgment from the remote
node.
The XBee firmware will automatically attempt retransmits if they don't
get an ACK in the expected timeframe.
Although higher\-level protocols also will do ACK and retransmit, they
don't have the XBee level of knowledge of the link layer timing and so
XBee may be able to detect and correct for a missing packet much
quicker.
.PP
However, sometimes all these ACKs can cause significant degredation in
performance.
Whether or not they do for you will depend on your network topology and
usage patterns; you probably should just try it both ways.
Use \f[B]disable\-xbee\-acks\f[] to disable the XBee level ACKs on
messages sent from a given node and see what it does.
.SS PROTOCOL SELECTION
.PP
If all you really need is point\-to\-point, then consider using PPP
rather than tun.
PPP supports header compression which may reduce the TCP/IP overhead
significantly.
.SS PACKET SIZE
.PP
Bear in mind the underlying packet size.
For low\-overhead protocols, you might want to use a packet size less
than the XBee packet size.
For high\-overhead protocols such as TCP, you may find that using large
packet sizes and letting \f[B]xbnet\f[] do fragmentation gives much
better performance on clean links, especially at the lower XBee
bitrates.
.SS SERIAL COMMUNICATION SPEED
.PP
By defualt, XBee modules communicate at 9600bps.
You should change this and write the updated setting to the module, and
give it to xbnet with \f[B]\[en]serial\-speed\f[].
.SH TROUBLESHOOTING
.SS BROADCAST ISSUES
.SH SECURITY
.PP
xbnet is a low\-level tool and should not be considered secure on its
own.
The \f[B]xbnet pipe\f[] command, for instance, will display information
from any node on your mesh.
Here are some tips:
.PP
Of course, begin by securing things at the XBee layer.
Enable encryption and passwords for remote AT commands in XBee.
.PP
If you are running a network protocol across XBee, enable firewalls at
every node on the network.
Remember, joining a node to a networked mesh is like giving it a port on
your switch! Consider how nodes can talk to each other.
.PP
Use encryption and authentication at the application layer as well.
ssh or gpg would be a fantastic choice here.
.PP
For nodes that are using xbnet to access the Internet, consider not
giving them direct Internet access, but rather requiring them to access
via something like OpenVPN or SSH forwarding.
.SH INSTALLATION
.PP
\f[B]lorapipe\f[] is a Rust program and can be built by running
\f[B]xbnet\f[] is a Rust program and can be built by running
\f[B]\f[BC]cargo\ build\ \-\-release\f[B]\f[].
The executable will then be placed in \f[B]target/release/lorapipe\f[].
The executable will then be placed in \f[B]target/release/xbnet\f[].
Rust can be easily installed from <https://www.rust-lang.org/>.
.SH INVOCATION
.PP
Every invocation of \f[B]lorapipe\f[] requires at least the name of a
Every invocation of \f[B]xbnet\f[] requires at least the name of a
serial port (for instance, \f[B]/dev/ttyUSB0\f[]) and a subcommand to
run.
.SH GLOBAL OPTIONS
@ -363,47 +442,47 @@ Display brief help on program operation.
.RS
.RE
.TP
.B \f[B]\[en]readqual\f[]
Attempt to read and log information about the RF quality of incoming
packets after each successful packet received.
There are some corner cases where this is not possible.
The details will be logged with \f[B]lorapipe\f[]'s logging facility,
and are therefore only visible if \f[B]\[en]debug\f[] is also used.
.RS
.RE
.TP
.B \f[B]\-V\f[], \f[B]\[en]version\f[]
Display the version number of \f[B]lorapipe\f[].
.RS
.RE
.TP
.B \f[B]\[en]eotwait\f[] \f[I]TIME\f[]
The amount of time in milliseconds to wait after receiving a packet that
indicates more are coming before giving up on receiving an additional
packet and proceeding to transmit.
Ideally this would be at least the amount of time it takes to transmit 2
packets.
Default: 1000.
.B \f[B]\[en]disable\-xbee\-acks\f[]
Disable the XBee protocol\-level acknowledgments of transmitted packets.
This may improve, or hurt, performance; see the conversation under the
PERFORMANCE TUNING section.
.RS
.RE
.TP
.B \f[B]\[en]initfile\f[] \f[I]FILE\f[]
A file listing commands to send to the radio to initialize it.
If not given, a default set will be used.
Each command must yield an \f[C]OK\f[] result from the radio.
After running these commands, \f[B]xbnet\f[] will issue additional
commands to ensure the radio is in the operating mode required by
\f[B]xbnet\f[].
Enable \f[B]\[en]debug\f[] to see all initialization activity.
.RS
.RE
.TP
.B \f[B]\[en]txwait\f[] \f[I]TIME\f[]
Amount of time in milliseconds to pause before transmitting each packet.
Due to processing delays on the receiving end, packets cannot be
transmitted immediately back to back.
Increase this if you are seeing frequent receive errors for
back\-to\-back packets, which may be indicative of a late listen.
Experimentation has shown that a value of 120 is needed for very large
packets, and is the default.
You may be able to use 50ms or less if you are sending small packets.
In my testing, with 100\-byte packets, a txwait of 50 was generally
sufficient.
.B \f[B]\[en]request\-xbee\-tx\-reports\f[]
The XBee firmware can return back a report about the success or failure
of a transmission.
\f[B]xbnet\f[] has no use for these reports, though they are displayed
for you if \f[B]\[en]debug\f[] is given.
By default, \f[B]xbnet\f[] suppresses the generation of these reports.
If you give this option and \f[B]\[en]debug\f[], then you can see them.
.RS
.RE
.TP
.B \f[B]\[en]serial\-speed\f[] \f[I]SPEED\f[]
Communicate with the XBee module at the given serial speed, given in
bits per second (baud rate).
If not given, defaults to 9600, which is the Digi default for the XBee
modules.
You can change this default with XBee commands and save the new default
persistently to the board.
It is strongly recommended that you do so, because many XBee modules can
communicate much faster than 9600bps.
.RS
.RE
.TP
.B \f[B]\-V\f[], \f[B]\[en]version\f[]
Display the version number of \f[B]xbnet\f[].
.RS
.RE
.TP
@ -417,37 +496,88 @@ The subcommand which will be executed.
.RS
.RE
.SH SUBCOMMANDS
.SS lorapipe \&... pipe
.SS xbnet \&... pipe
.PP
The \f[B]pipe\f[] subcommand is the main workhorse of the application
and is described extensively above.
It has one optional parameter:
.TP
.B \f[B]\[en]maxpacketsize\f[] \f[I]BYTES\f[]
The maximum frame size, in the range of 10 \- 250.
The actual frame transmitted over the air will be one byte larger due to
\f[B]lorapipe\f[] collision mitigation as described above.
Experimentation myself, and reports from others, suggests that LoRa
works best when this is 100 or less.
.RS
.RE
.SS lorapipe \&... ping
The \f[B]pipe\f[] subcommand permits piping data between radios.
It requires a \f[B]\[en]dest\f[] parameter, which gives the hex MAC
address of the recipient of data sent to xbnet's stdin.
pipe is described extensively above.
.PP
The \f[B]ping\f[] subcommand will transmit a simple line of text every
10 seconds including an increasing counter.
It can be displayed at the other end with \f[B]lorapipe \&... pipe\f[]
or reflected with \f[B]lorapipe \&... pong\f[].
.SS lorapipe \&... pong
Note that \f[B]\[en]dest\f[] will not restrict the devices that xbnet
will receive data from.
.SS xbnet \&... ping
.PP
The \f[B]ping\f[] subcommand will transmit a simple line of text every 5
seconds including an increasing counter.
It can be displayed at the other end with \f[B]xbnet \&... pipe\f[] or
reflected with \f[B]xbnet \&... pong\f[].
Like \f[B]pipe\f[], it requires a destination MAC address.
.SS xbnet \&... pong
.PP
The \f[B]pong\f[] subcommand receives packets and crafts a reply.
It is intended to be used with \f[B]lorapipe \&... ping\f[].
Its replies include the signal quality SNR and RSSI if available.
It is intended to be used with \f[B]xbnet \&... ping\f[].
.SS xbnet \&... tun & tap
.PP
These commands run a network stack across XBee and are described
extensively above.
They have several optional parameters:
.TP
.B \f[B]\[en]broadcast\-everything\f[] (tun and tap)
Normally, \f[B]xbnet\f[] will use unicast (directed) transmissions to
remotes where it knows their XBee MAC address.
This is more efficient on the XBee network.
However, in some cases you may simply want it to use broadcast packets
for all transmissions, and this accomplishes that.
.RS
.RE
.TP
.B \f[B]\[en]broadcast\-unknown\f[] (tap only)
Normally, \f[B]xbnet\f[] will drop Ethernet frames destined for MAC
addresses that it hasn't seen.
(Broadcast packets still go out.) This is suitable for most situations.
However, you can also have it broadcast all packets do unknown MAC
addresses.
This can be useful in some obscure situations such as multicast.
.RS
.RE
.TP
.B \f[B]\[en]disable\-ipv4\f[] and \f[B]disable\-ipv6\f[] (tun only)
Disable all relaying of either IPv4 or IPv6 packets.
This is not valid in tap mode because tap doesn't operate at this
protocol level.
It is recommended you disable protocols you don't use.
.RS
.RE
.TP
.B \f[B]\[en]iface\-name\f[] \f[I]NAME\f[] (tun and tap)
Request a specific name for the tun or tap interface.
By default, this requests \f[B]xbnet%d\f[].
The kernel replaces \f[B]%d\f[] with an integer starting at 0, finding
an unused interface.
It can be useful to specify an explicit interface here for use in
scripts.
.RS
.RE
.TP
.B \f[B]\[en]max\-ip\-cache\f[] \f[I]SECONDS\f[] (tun only)
Specifies how long it caches the XBee MAC address for a given IP
address.
After this many seconds without receiving a packet from the given IP
address, \f[B]xbnet\f[] will send the next packet to the IP as a
broadcast and then cache the result.
The only reason to expire IPs from the cache is if you re\-provision
them on other devices.
The tap mode doesn't have a timed cache, since the OS will re\-ARP
(generating a broadcast anyhow) if it fails to communicate with a given
IP.
.RS
.RE
.SH AUTHOR
.PP
John Goerzen <jgoerzen@complete.org>
.SH COPYRIGHT AND LICENSE
.PP
Copyright (C) 2019 John Goerzen <jgoerzen\@complete.org
Copyright (C) 2019\-2020 John Goerzen <jgoerzen@complete.org>
.PP
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the