2022-12-17 22:01:33 +00:00
|
|
|
#ifndef LORAPRS_SERVICE_H
|
2020-06-14 18:55:27 +00:00
|
|
|
#define LORAPRS_SERVICE_H
|
2019-04-25 06:17:02 +00:00
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <SPI.h>
|
2021-10-22 19:09:17 +00:00
|
|
|
#include <DebugLog.h>
|
2021-10-20 10:20:19 +00:00
|
|
|
|
2021-11-15 13:44:37 +00:00
|
|
|
// some generic options (module name, library type) are loaded from config.h
|
|
|
|
#if __has_include("/tmp/esp32_loraprs_config.h")
|
|
|
|
#include "/tmp/esp32_loraprs_config.h"
|
|
|
|
#else
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2021-10-20 10:20:19 +00:00
|
|
|
#include <RadioLib.h>
|
|
|
|
|
2019-04-25 06:17:02 +00:00
|
|
|
#include <WiFi.h>
|
2021-02-05 16:57:06 +00:00
|
|
|
#include <endian.h>
|
2022-12-17 22:01:33 +00:00
|
|
|
#include <arduino-timer.h>
|
2019-04-25 06:17:02 +00:00
|
|
|
|
|
|
|
#include "BluetoothSerial.h"
|
2021-06-08 05:33:40 +00:00
|
|
|
#include "ble_serial.h"
|
2020-06-12 14:53:21 +00:00
|
|
|
#include "ax25_payload.h"
|
2021-02-02 15:53:28 +00:00
|
|
|
#include "kiss_processor.h"
|
2020-06-14 18:55:27 +00:00
|
|
|
#include "loraprs_config.h"
|
2020-06-12 14:34:23 +00:00
|
|
|
|
2020-06-14 18:55:27 +00:00
|
|
|
namespace LoraPrs {
|
2019-04-25 06:17:02 +00:00
|
|
|
|
2022-12-19 10:16:14 +00:00
|
|
|
class Service : virtual public Kiss::Processor
|
2019-04-25 06:17:02 +00:00
|
|
|
{
|
|
|
|
public:
|
2020-06-14 18:55:27 +00:00
|
|
|
Service();
|
2019-05-09 16:13:08 +00:00
|
|
|
|
2020-06-14 18:55:27 +00:00
|
|
|
void setup(const Config &conf);
|
2019-05-09 16:13:08 +00:00
|
|
|
void loop();
|
|
|
|
|
|
|
|
private:
|
2022-12-22 19:39:43 +00:00
|
|
|
void printConfig() const;
|
2021-10-26 13:36:16 +00:00
|
|
|
|
2020-06-01 07:43:13 +00:00
|
|
|
void setupWifi(const String &wifiName, const String &wifiKey);
|
2022-12-03 13:43:37 +00:00
|
|
|
void setupRig(long freq, long bw, int sf, int cr, int pwr, int sync, int crcBytes, bool isExplicit);
|
|
|
|
void setFreq(long freq) const;
|
2020-06-01 07:43:13 +00:00
|
|
|
void setupBt(const String &btName);
|
2019-05-09 16:13:08 +00:00
|
|
|
|
2021-02-02 09:18:46 +00:00
|
|
|
void reconnectWifi() const;
|
2020-06-12 14:34:23 +00:00
|
|
|
bool reconnectAprsis();
|
2021-10-21 18:25:35 +00:00
|
|
|
void attachKissNetworkClient();
|
2021-02-12 14:33:25 +00:00
|
|
|
|
2022-12-29 16:54:13 +00:00
|
|
|
inline bool isRigRxBusy() const { return config_.LoraUseCad && rigIsRxActive_; }
|
|
|
|
|
2022-12-03 13:43:37 +00:00
|
|
|
void onRigTaskRxPacket();
|
|
|
|
void onRigTaskTxPacket();
|
|
|
|
static void rigTask(void *self);
|
|
|
|
static ICACHE_RAM_ATTR void onRigIsrRxPacket();
|
|
|
|
|
2020-06-13 22:15:05 +00:00
|
|
|
void onAprsisDataAvailable();
|
2021-10-22 19:20:17 +00:00
|
|
|
|
2021-02-05 16:57:06 +00:00
|
|
|
void sendSignalReportEvent(int rssi, float snr);
|
2022-12-17 22:01:33 +00:00
|
|
|
static bool sendModemTelemetryTimer(void *param);
|
|
|
|
void sendModemTelemetry();
|
2020-06-19 07:39:49 +00:00
|
|
|
void sendPeriodicBeacon();
|
2021-02-02 08:32:32 +00:00
|
|
|
void sendToAprsis(const String &aprsMessage);
|
2022-12-03 13:43:37 +00:00
|
|
|
bool sendAx25PayloadToRig(const AX25::Payload &payload);
|
2021-02-02 09:18:46 +00:00
|
|
|
void processIncomingRawPacketAsServer(const byte *packet, int packetLength);
|
2021-10-26 12:34:08 +00:00
|
|
|
void performFrequencyCorrection();
|
2021-10-22 19:20:17 +00:00
|
|
|
|
2021-02-02 08:26:11 +00:00
|
|
|
inline bool needsAprsis() const {
|
2021-10-21 12:43:38 +00:00
|
|
|
return !config_.IsClientMode // only in server mode
|
|
|
|
&& (config_.EnableRfToIs || config_.EnableIsToRf) // rx/tx igate enabled
|
|
|
|
&& !config_.WifiEnableAp; // wifi is NOT in AP mode
|
|
|
|
}
|
|
|
|
inline bool needsWifi() const {
|
|
|
|
return needsAprsis() // aprsis is needed
|
|
|
|
|| config_.KissEnableTcpIp; // or kiss over tcp ip is enabled
|
2021-02-02 08:26:11 +00:00
|
|
|
}
|
2021-10-22 19:20:17 +00:00
|
|
|
inline bool needsBt() const {
|
|
|
|
return (config_.IsClientMode || config_.BtName.length() > 0) // client mode or name must be specified
|
|
|
|
&& !config_.UsbSerialEnable; // inactive in usb serial mode
|
|
|
|
}
|
|
|
|
inline bool needsBeacon() const {
|
|
|
|
return !config_.IsClientMode // beaconing only in apris gate / server mode
|
|
|
|
&& config_.EnableBeacon; // beacon must be explicitly enabled
|
|
|
|
}
|
2022-12-22 13:14:37 +00:00
|
|
|
inline bool isHalfDuplex() const {
|
2022-03-11 19:30:50 +00:00
|
|
|
return config_.LoraFreqRx != config_.LoraFreqTx;
|
|
|
|
}
|
2020-06-14 14:59:35 +00:00
|
|
|
|
2022-12-29 17:24:39 +00:00
|
|
|
inline int getSpeed(int sf, int cr, long bw) const { return (int)(sf * (4.0 / cr) / (pow(2.0, sf) / bw)); }
|
|
|
|
float getSnrLimit(int sf, long bw) const;
|
|
|
|
|
2021-02-02 15:53:28 +00:00
|
|
|
protected:
|
2022-12-19 10:16:14 +00:00
|
|
|
virtual bool onRigTxBegin() override;
|
|
|
|
virtual void onRigTx(byte b) override;
|
|
|
|
virtual void onRigTxEnd() override;
|
|
|
|
virtual void onRigPacket(void *packet, int packetLength) override;
|
2021-02-12 14:33:25 +00:00
|
|
|
|
2022-12-19 10:16:14 +00:00
|
|
|
virtual void onSerialTx(byte b) override;
|
|
|
|
virtual bool onSerialRxHasData() override;
|
|
|
|
virtual bool onSerialRx(byte *b) override;
|
2019-05-09 16:13:08 +00:00
|
|
|
|
2022-12-19 10:16:14 +00:00
|
|
|
virtual void onControlCommand(Cmd cmd, byte value) override;
|
|
|
|
virtual void onRadioControlCommand(const std::vector<byte> &command) override;
|
|
|
|
virtual void onRebootCommand() override;
|
2021-02-05 16:57:06 +00:00
|
|
|
|
|
|
|
private:
|
2021-02-08 18:30:23 +00:00
|
|
|
struct SetHardware {
|
2021-02-06 13:53:19 +00:00
|
|
|
uint32_t freq;
|
|
|
|
uint32_t bw;
|
|
|
|
uint16_t sf;
|
|
|
|
uint16_t cr;
|
|
|
|
uint16_t pwr;
|
|
|
|
uint16_t sync;
|
|
|
|
uint8_t crc;
|
2021-02-05 16:57:06 +00:00
|
|
|
} __attribute__((packed));
|
|
|
|
|
2021-02-08 18:30:23 +00:00
|
|
|
struct SignalReport {
|
|
|
|
int16_t rssi;
|
|
|
|
int16_t snr;
|
|
|
|
} __attribute__((packed));
|
2022-12-17 22:01:33 +00:00
|
|
|
|
|
|
|
struct Telemetry {
|
|
|
|
int16_t batteryVoltage;
|
|
|
|
} __attribute__((packed));
|
2022-12-19 09:12:31 +00:00
|
|
|
|
2021-02-02 15:53:28 +00:00
|
|
|
private:
|
2022-12-22 19:39:43 +00:00
|
|
|
const String CfgLoraprsVersion = "LoRAPRS 1.0.10";
|
2020-06-20 09:50:57 +00:00
|
|
|
|
2021-02-02 09:18:46 +00:00
|
|
|
// processor config
|
2022-12-03 13:43:37 +00:00
|
|
|
const int CfgConnRetryMs = 500; // connection retry delay, e.g. wifi
|
|
|
|
const int CfgConnRetryMaxTimes = 10; // number of connection retries
|
2022-12-19 09:00:27 +00:00
|
|
|
const int CfgTelemetryPeriodMs = 60000; // how often to send telemetry event
|
2022-12-17 22:01:33 +00:00
|
|
|
|
2022-12-03 13:43:37 +00:00
|
|
|
static const int CfgMaxPacketSize = 256; // maximum packet size
|
|
|
|
static const int CfgRadioQueueSize = 1024; // radio queue size
|
2020-06-20 09:50:57 +00:00
|
|
|
|
2021-02-05 16:57:06 +00:00
|
|
|
// csma parameters, overriden with KISS commands
|
2021-02-02 16:10:12 +00:00
|
|
|
const long CfgCsmaPersistence = 100; // 255 for real time, lower for higher traffic
|
|
|
|
const long CfgCsmaSlotTimeMs = 500; // 0 for real time, otherwise set to average tx duration
|
2021-10-21 12:18:11 +00:00
|
|
|
|
|
|
|
// kiss static parameters
|
2021-10-21 18:25:35 +00:00
|
|
|
const int CfgKissPort = 8001; // kiss tcp/ip server port
|
2022-12-03 13:43:37 +00:00
|
|
|
|
|
|
|
// radio task commands
|
|
|
|
enum RadioTaskBits {
|
|
|
|
Receive = 0x01,
|
|
|
|
Transmit = 0x02
|
|
|
|
};
|
|
|
|
|
2019-04-25 06:17:02 +00:00
|
|
|
private:
|
2020-06-14 14:59:35 +00:00
|
|
|
// config
|
2021-02-02 08:26:11 +00:00
|
|
|
Config config_;
|
2021-02-02 15:57:36 +00:00
|
|
|
String aprsLoginCommand_;
|
2022-12-03 13:43:37 +00:00
|
|
|
AX25::Callsign aprsMyCallsign_;
|
2021-02-02 15:57:36 +00:00
|
|
|
|
|
|
|
// csma
|
2021-02-02 08:26:11 +00:00
|
|
|
byte csmaP_;
|
|
|
|
long csmaSlotTime_;
|
2021-02-02 15:53:28 +00:00
|
|
|
long csmaSlotTimePrev_;
|
2020-06-14 14:59:35 +00:00
|
|
|
|
2022-12-03 13:43:37 +00:00
|
|
|
// beacon state
|
|
|
|
long beaconLastTimestampMs_;
|
|
|
|
|
|
|
|
// peripherals, radio
|
|
|
|
static TaskHandle_t rigTaskHandle_;
|
|
|
|
static volatile bool rigIsRxActive_;
|
2022-12-03 13:56:22 +00:00
|
|
|
static volatile bool rigIsRxIsrEnabled_;
|
2022-12-03 13:43:37 +00:00
|
|
|
bool rigIsImplicitMode_;
|
|
|
|
int rigCurrentTxPacketSize_;
|
2022-12-10 09:20:19 +00:00
|
|
|
bool isIsrInstalled_;
|
2022-12-03 13:43:37 +00:00
|
|
|
CircularBuffer<uint8_t, CfgRadioQueueSize> rigTxQueue_;
|
|
|
|
CircularBuffer<uint8_t, CfgRadioQueueSize> rigTxQueueIndex_;
|
|
|
|
std::shared_ptr<MODULE_NAME> rig_;
|
|
|
|
|
|
|
|
// bluetooth, wifi
|
2019-05-09 16:13:08 +00:00
|
|
|
BluetoothSerial serialBt_;
|
2021-06-08 05:33:40 +00:00
|
|
|
BLESerial serialBLE_;
|
2022-12-03 13:43:37 +00:00
|
|
|
WiFiClient aprsisConnection_;
|
2021-10-21 18:25:35 +00:00
|
|
|
|
2022-12-03 13:43:37 +00:00
|
|
|
// kiss server
|
2021-10-21 12:18:11 +00:00
|
|
|
std::shared_ptr<WiFiServer> kissServer_;
|
2022-12-03 13:43:37 +00:00
|
|
|
WiFiClient kissConnnection_;
|
|
|
|
bool isKissClientConnected_;
|
2022-12-17 22:01:33 +00:00
|
|
|
|
|
|
|
// modem telemetry
|
|
|
|
Timer<1> telemetryTimer_;
|
2019-04-25 06:17:02 +00:00
|
|
|
};
|
|
|
|
|
2020-06-14 18:55:27 +00:00
|
|
|
} // LoraPrs
|
|
|
|
|
|
|
|
#endif // LORAPRS_SERVICE_H
|