// Copyright (C)2025, Philip Munts dba Munts Technologies. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. using System; using static System.Environment; using static IO.Bindings.libwioe5ham2; namespace IO.Devices.WioE5.Ham2 { /// /// Encapsulates the /// /// Wio-E5 LoRa Transceiver Module in test aka P2P (Point to /// Point or Peer to Peer) broadcast mode, adding Amateur Radio Unicast /// Flavor #2 (Local Area Network with stations using different network /// ID's aka call signs) address information. /// /// /// See more information. /// public class Device { private readonly int handle; /// /// Constructor for a Wio-E5 LoRa Transceiver Module device object /// instance. /// /// Serial Port device name e.g. /// "/dev/ttyAMA0" or "/dev/ttyUSB0" or "COM1". /// /// Serial port data rate in bits per second /// (9600, 19200, 38400, 57600, 115200, or 230400). /// Network ID aka callsign, 10 ASCII /// characters, left justified and automatically space padded /// e.g. "WA7AAA" or "KL7/SA7AAA". /// Node ID, ARCNET Style: 1 to 255. /// RF center frequency in MHz, 902.0 to 928.0 /// (U.S. /// Amateur Radio Allocation). /// Spreading Factor, 7 to 12. /// Bandwidth in kHz, 125, 250, or 500. /// Number of transmit preamble bits. /// Number of receive preamble bits. /// Transmit power in dBm, -1 to 22. public Device(string portname, int baudrate, string network, int node, float freq, int spreading = 7, int bandwidth = 500, int txpreamble = 12, int rxpreamble = 15, int power = 22) { wioe5ham2_init(portname, baudrate, network, node, freq, spreading, bandwidth, txpreamble, rxpreamble, power, out this.handle, out int error); if (error != 0) { throw new Exception("wioe5ham2_init() failed, " + errno.strerror(error)); } } /// /// Parameterless constructor for a Wio-E5 LoRa Transceiver Module /// device object instance. Settings are obtained from environment /// variables, some of which have default values. /// /// /// This is mostly for /// MuntsOS Embedded Linux targets with /// configuration parameters defined in /etc/environment /// using the following environment variables: /// /// WIOE5_PORT
/// WIOE5_BAUD (Default: 115200)
/// WIOE5_NETWORK
/// WIOE5_NODE
/// WIOE5_FREQ
/// WIOE5_SPREADING (Default: 7)
/// WIOE5_BANDWIDTH (Default: 500)
/// WIOE5_TXPREAMBLE (Default: 12)
/// WIOE5_RXPREAMBLE (Default: 15)
/// WIOE5_TXPOWER (Default: 22)
///
public Device() { var port = GetEnvironmentVariable("WIOE5_PORT"); if (port == null) { throw new Exception("WIOE5_PORT environment variable is undefined"); } var sbaudrate = GetEnvironmentVariable("WIOE5_BAUD"); if (sbaudrate == null) { sbaudrate = "115200"; } if (!int.TryParse(sbaudrate, out int baudrate)) { throw new Exception("WIOE5_PORT environment variable is invalid"); } var network = GetEnvironmentVariable("WIOE5_NETWORK"); if (network == null) { throw new Exception("WIOE5_NETWORK environment variable is undefined"); } var snode = GetEnvironmentVariable("WIOE5_NODE"); if (snode == null) { throw new Exception("WIOE5_NODE environment variable is undefined"); } if (!int.TryParse(snode, out int node)) { throw new Exception("WIOE5_NODE environment variable is undefined"); } var sfreq = GetEnvironmentVariable("WIOE5_FREQ"); if (sfreq == null) { throw new Exception("WIOE5_FREQ environment variable is undefined"); } if (!float.TryParse(sfreq, out float freq)) { throw new Exception("WIOE5_FREQ environment variable is invalid"); } var sspreading = GetEnvironmentVariable("WIOE5_SPREADING"); if (sspreading == null) { sspreading = "7"; } if (!int.TryParse(sspreading, out int spreading)) { throw new Exception("WIOE5_FREQ environment variable is invalid"); } var sbandwidth = GetEnvironmentVariable("WIOE5_BANDWIDTH"); if (sbandwidth == null) { sbandwidth = "500"; } if (!int.TryParse(sbandwidth, out int bandwidth)) { throw new Exception("WIOE5_BANDWIDTH environment variable is invalid"); } var stxpreamble = GetEnvironmentVariable("WIOE5_TXPREAMBLE"); if (stxpreamble == null) { stxpreamble = "12"; } if (!int.TryParse(stxpreamble, out int txpreamble)) { throw new Exception("WIOE5_TXPREAMBLE environment variable is invalid"); } var srxpreamble = GetEnvironmentVariable("WIOE5_RXPREAMBLE"); if (srxpreamble == null) { srxpreamble = "15"; } if (!int.TryParse(srxpreamble, out int rxpreamble)) { throw new Exception("WIOE5_RXPREAMBLE environment variable is invalid"); } var spower = GetEnvironmentVariable("WIOE5_POWER"); if (spower == null) { spower = "22"; } if (!int.TryParse(spower, out int power)) { throw new Exception("WIOE5_POWER environment variable is invalid"); } wioe5ham2_init(port, baudrate, network, node, freq, spreading, bandwidth, txpreamble, rxpreamble, power, out this.handle, out int error); if (error != 0) { throw new Exception("wioe5ham2_init() failed, " + errno.strerror(error)); } } /// /// Finalizer for a Wio-E5 LoRa Transceiver Module device object /// instance. /// ~Device() { wioe5ham2_exit(handle, out int error); } /// /// Send a text message. /// /// Text message to send. Must be 1 to 241 /// characters. /// Destination network ID. /// Destination node ID (ARCNET style: 0=broadcast, /// or 1 to 255). public void Send(string s, string dstnet, int dstnode) { wioe5ham2_send_string(this.handle, s, dstnet, dstnode, out int error); if (error != 0) { throw new Exception("wioe5ham2_send_string() failed, " + errno.strerror(error)); } } /// /// Send a binary message. /// /// Binary message. /// Message length in bytes, 1 to 241. /// Destination network ID. /// Destination node ID (ARCNET style: 0=broadcast, /// or 1 to 255). public void Send(byte[] msg, int len, string dstnet, int dstnode) { wioe5ham2_send(this.handle, msg, len, dstnet, dstnode, out int error); if (error != 0) { throw new Exception("wioe5ham2_receive() failed, " + errno.strerror(error)); } } /// /// Receive a binary message. /// /// Binary message. Must be at least 241 bytes. /// /// Number of bytes received. /// Source network ID. /// Source node ID (ARCNET style: 1 to 255). /// Destination network ID. /// Destination node ID (ARCNET style: 0=broadcast, /// or 1 to 255). /// Received Signal Strength in dBm. /// Signal to Noise Ratio in dB. public void Receive(byte[]msg, out int len, out string srcnet, out int srcnode, out string dstnet, out int dstnode, out int RSS, out int SNR) { var cdstnet = new char[11]; var csrcnet = new char[11]; wioe5ham2_receive(this.handle, msg, out len, csrcnet, out srcnode, cdstnet, out dstnode, out RSS, out SNR, out int error); if (error != 0) { throw new Exception("wioe5ham2_receive() failed, " + errno.strerror(error)); } srcnet = new string(csrcnet).Trim(' '); dstnet = new string(cdstnet).Trim(' '); } } }