kopia lustrzana https://github.com/sh123/esp32_loraprs
Config and AX25 message reafactoring (#5)
* Refactoring * Add support for aprsis filter and print out incoming packets into the serialpull/6/head
rodzic
80963bdf11
commit
1ae790c5d5
|
@ -0,0 +1,88 @@
|
||||||
|
#include "aprsmsg.h"
|
||||||
|
|
||||||
|
namespace AX25 {
|
||||||
|
|
||||||
|
Payload::Payload(byte *rxPayload, int payloadLength)
|
||||||
|
{
|
||||||
|
parsePayload(rxPayload, payloadLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
String Payload::ToText(const String &customComment)
|
||||||
|
{
|
||||||
|
String txt = srcCall_ + String(">") + dstCall_;
|
||||||
|
|
||||||
|
if (rptFirst_.length() > 0) {
|
||||||
|
txt += String(",") + rptFirst_;
|
||||||
|
}
|
||||||
|
if (rptSecond_.length() > 0) {
|
||||||
|
txt += String(",") + rptSecond_;
|
||||||
|
}
|
||||||
|
|
||||||
|
txt += String(":") + body_;
|
||||||
|
|
||||||
|
if (body_.startsWith("=")) {
|
||||||
|
txt += customComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return txt + String("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Payload::parsePayload(byte *rxPayload, int payloadLength)
|
||||||
|
{
|
||||||
|
byte *rxPtr = rxPayload;
|
||||||
|
|
||||||
|
dstCall_ = decodeCall(rxPtr);
|
||||||
|
rxPtr += CallsignSize;
|
||||||
|
if (rxPtr >= rxPayload + payloadLength) return false;
|
||||||
|
|
||||||
|
srcCall_ = decodeCall(rxPtr);
|
||||||
|
rxPtr += CallsignSize;
|
||||||
|
if (rxPtr >= rxPayload + payloadLength) return false;
|
||||||
|
|
||||||
|
if ((rxPayload[2 * CallsignSize - 1] & 1) == 0) {
|
||||||
|
rptFirst_ = decodeCall(rxPtr);
|
||||||
|
rxPtr += CallsignSize;
|
||||||
|
if (rxPtr >= rxPayload + payloadLength) return false;
|
||||||
|
|
||||||
|
if ((rxPayload[3 * CallsignSize - 1] & 1) == 0) {
|
||||||
|
rptSecond_ = decodeCall(rxPtr);
|
||||||
|
rxPtr += CallsignSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((rxPtr + 1) >= rxPayload + payloadLength) return false;
|
||||||
|
|
||||||
|
if (*(rxPtr++) != AX25Ctrl::UI) return false;
|
||||||
|
if (*(rxPtr++) != AX25Pid::NoLayer3) return false;
|
||||||
|
|
||||||
|
while (rxPtr < rxPayload + payloadLength) {
|
||||||
|
body_ += String((char)*(rxPtr++));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String Payload::decodeCall(byte *rxPtr)
|
||||||
|
{
|
||||||
|
byte callsign[CallsignSize];
|
||||||
|
char ssid;
|
||||||
|
|
||||||
|
byte *ptr = rxPtr;
|
||||||
|
|
||||||
|
memset(callsign, 0, sizeof(callsign));
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
char c = *(ptr++) >> 1;
|
||||||
|
callsign[i] = (c == ' ') ? '\0' : c;
|
||||||
|
}
|
||||||
|
callsign[CallsignSize-1] = '\0';
|
||||||
|
ssid = (*ptr >> 1);
|
||||||
|
|
||||||
|
String result = String((char*)callsign);
|
||||||
|
|
||||||
|
if (result.length() > 0 && ssid >= '0' && ssid <= '9') {
|
||||||
|
result += String("-") + String(ssid);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AX25
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef APRSMSG_H
|
||||||
|
#define APRSMSG_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
namespace AX25 {
|
||||||
|
|
||||||
|
class Payload
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Payload(byte *rxPayload, int payloadLength);
|
||||||
|
String ToText(const String &customComment);
|
||||||
|
|
||||||
|
private:
|
||||||
|
String decodeCall(byte *rxPtr);
|
||||||
|
bool parsePayload(byte *rxPayload, int payloadLength);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum AX25Ctrl {
|
||||||
|
UI = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AX25Pid {
|
||||||
|
NoLayer3 = 0xf0
|
||||||
|
};
|
||||||
|
|
||||||
|
const int MaxPayloadSize = 16;
|
||||||
|
const int CallsignSize = 7;
|
||||||
|
|
||||||
|
private:
|
||||||
|
String srcCall_, dstCall_;
|
||||||
|
String rptFirst_, rptSecond_;
|
||||||
|
String body_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AX25
|
||||||
|
|
||||||
|
#endif // APRSMSG_H
|
|
@ -5,46 +5,39 @@
|
||||||
#define LED_BUILTIN 2
|
#define LED_BUILTIN 2
|
||||||
#define LED_TOGGLE_PERIOD 1000
|
#define LED_TOGGLE_PERIOD 1000
|
||||||
|
|
||||||
#define LORAPRS_CLIENT
|
LoraPrsConfig cfg;
|
||||||
|
LoraPrs loraPrs;
|
||||||
// https://vienna.iaru-r1.org/wp-content/uploads/2019/01/VIE19-C5-015-OEVSV-LORA-APRS-433-MHz.pdf
|
|
||||||
#ifdef LORAPRS_CLIENT
|
|
||||||
// calibrate client based on server frequency drift report
|
|
||||||
#define LORAPRS_FREQ 433.775E6
|
|
||||||
//#define LORAPRS_FREQ 433.7688E6
|
|
||||||
#else
|
|
||||||
#define LORAPRS_FREQ 433.775E6
|
|
||||||
//#define LORAPRS_FREQ 433.770E6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LORAPRS_CLIENT
|
|
||||||
#define LORAPRS_BT_NAME "loraprs_client"
|
|
||||||
#define LORAPRS_WIFI_SSID ""
|
|
||||||
#define LORAPRS_WIFI_KEY ""
|
|
||||||
#define LORAPRS_LOGIN "NOCALL-0"
|
|
||||||
#define LORAPRS_PASS "00000"
|
|
||||||
#define LORAPRS_FREQ_CORR false
|
|
||||||
#else
|
|
||||||
#define LORAPRS_BT_NAME ""
|
|
||||||
#define LORAPRS_WIFI_SSID "<your access point name>"
|
|
||||||
#define LORAPRS_WIFI_KEY "<your access point key>"
|
|
||||||
#define LORAPRS_LOGIN "NOCALL-0"
|
|
||||||
#define LORAPRS_PASS "12345"
|
|
||||||
#define LORAPRS_FREQ_CORR false
|
|
||||||
//#define LORAPRS_FREQ_CORR true
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LoraPrs loraPrs(
|
|
||||||
LORAPRS_FREQ,
|
|
||||||
LORAPRS_BT_NAME,
|
|
||||||
LORAPRS_WIFI_SSID,
|
|
||||||
LORAPRS_WIFI_KEY,
|
|
||||||
LORAPRS_LOGIN,
|
|
||||||
LORAPRS_PASS,
|
|
||||||
LORAPRS_FREQ_CORR);
|
|
||||||
|
|
||||||
auto watchdogLedTimer = timer_create_default();
|
auto watchdogLedTimer = timer_create_default();
|
||||||
|
|
||||||
|
void initializeConfig() {
|
||||||
|
cfg.IsClientMode = true;
|
||||||
|
|
||||||
|
cfg.LoraFreq = 433.775E6; // 433.7688E6;
|
||||||
|
cfg.LoraBw = 125e3;
|
||||||
|
cfg.LoraSf = 12;
|
||||||
|
cfg.LoraCodingRate = 7;
|
||||||
|
cfg.LoraSync = 0xf3;
|
||||||
|
cfg.LoraPower = 20;
|
||||||
|
|
||||||
|
cfg.AprsHost = "rotate.aprs2.net";
|
||||||
|
cfg.AprsPort = 14580;
|
||||||
|
cfg.AprsLogin = "NOCALL-1";
|
||||||
|
cfg.AprsPass = "00000";
|
||||||
|
cfg.AprsFilter = "r/35.60/139.80/25";
|
||||||
|
|
||||||
|
cfg.BtName = "loraprs";
|
||||||
|
|
||||||
|
cfg.WifiSsid = "<wifi ssid>";
|
||||||
|
cfg.WifiKey = "<wifi key>";
|
||||||
|
|
||||||
|
cfg.EnableSignalReport = true;
|
||||||
|
cfg.EnableAutoFreqCorrection = true;
|
||||||
|
cfg.EnablePersistentAprsConnection = true;
|
||||||
|
cfg.EnableIsToRf = false;
|
||||||
|
cfg.EnableRepeater = false;
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
digitalWrite(LED_BUILTIN, 1);
|
digitalWrite(LED_BUILTIN, 1);
|
||||||
|
@ -52,7 +45,8 @@ void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
while (!Serial);
|
while (!Serial);
|
||||||
|
|
||||||
loraPrs.setup();
|
initializeConfig();
|
||||||
|
loraPrs.setup(cfg);
|
||||||
|
|
||||||
watchdogLedTimer.every(LED_TOGGLE_PERIOD, toggleWatchdogLed);
|
watchdogLedTimer.every(LED_TOGGLE_PERIOD, toggleWatchdogLed);
|
||||||
}
|
}
|
||||||
|
|
197
loraprs.cpp
197
loraprs.cpp
|
@ -1,36 +1,46 @@
|
||||||
#include "loraprs.h"
|
#include "loraprs.h"
|
||||||
|
|
||||||
LoraPrs::LoraPrs(long loraFreq, const String &btName, const String &wifiName, const String &wifiKey,
|
LoraPrs::LoraPrs()
|
||||||
const String &aprsLoginCallsign, const String &aprsPass, bool autoCorrectFreq)
|
|
||||||
: serialBt_()
|
: serialBt_()
|
||||||
, loraFreq_(loraFreq)
|
|
||||||
, autoCorrectFreq_(autoCorrectFreq)
|
|
||||||
, btName_(btName)
|
|
||||||
, wifiName_(wifiName)
|
|
||||||
, wifiKey_(wifiKey)
|
|
||||||
, kissState_(KissState::Void)
|
, kissState_(KissState::Void)
|
||||||
, kissCmd_(KissCmd::NoCmd)
|
, kissCmd_(KissCmd::NoCmd)
|
||||||
{
|
{
|
||||||
aprsLogin_ = "";
|
|
||||||
aprsLogin_ += "user ";
|
|
||||||
aprsLogin_ += aprsLoginCallsign;
|
|
||||||
aprsLogin_ += " pass ";
|
|
||||||
aprsLogin_ += aprsPass;
|
|
||||||
aprsLogin_ += " vers ";
|
|
||||||
aprsLogin_ += CfgLoraprsVersion;
|
|
||||||
aprsLogin_ += "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::setup()
|
void LoraPrs::setup(const LoraPrsConfig &conf)
|
||||||
{
|
{
|
||||||
setupWifi(wifiName_, wifiKey_);
|
isClient_ = conf.IsClientMode;
|
||||||
setupLora(loraFreq_);
|
loraFreq_ = conf.LoraFreq;
|
||||||
setupBt(btName_);
|
|
||||||
|
aprsLogin_ = String("user ") + conf.AprsLogin + String(" pass ") +
|
||||||
|
conf.AprsPass + String(" vers ") + CfgLoraprsVersion;
|
||||||
|
if (conf.AprsFilter.length() > 0) {
|
||||||
|
aprsLogin_ += String(" filter ") + conf.AprsFilter;
|
||||||
|
}
|
||||||
|
aprsLogin_ += String("\n");
|
||||||
|
|
||||||
|
aprsHost_ = conf.AprsHost;
|
||||||
|
aprsPort_ = conf.AprsPort;
|
||||||
|
|
||||||
|
autoCorrectFreq_ = conf.EnableAutoFreqCorrection;
|
||||||
|
addSignalReport_ = conf.EnableSignalReport;
|
||||||
|
persistentConn_ = conf.EnablePersistentAprsConnection;
|
||||||
|
enableIsToRf_ = conf.EnableIsToRf;
|
||||||
|
enableRepeater_ = conf.EnableRepeater;
|
||||||
|
|
||||||
|
setupWifi(conf.WifiSsid, conf.WifiKey);
|
||||||
|
|
||||||
|
setupLora(conf.LoraFreq, conf.LoraBw, conf.LoraSf, conf.LoraCodingRate, conf.LoraPower, conf.LoraSync);
|
||||||
|
setupBt(conf.BtName);
|
||||||
|
|
||||||
|
if (!isClient_ && persistentConn_) {
|
||||||
|
reconnectAprsis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::setupWifi(const String &wifiName, const String &wifiKey)
|
void LoraPrs::setupWifi(const String &wifiName, const String &wifiKey)
|
||||||
{
|
{
|
||||||
if (wifiName.length() != 0) {
|
if (!isClient_) {
|
||||||
Serial.print("WIFI connecting to " + wifiName);
|
Serial.print("WIFI connecting to " + wifiName);
|
||||||
|
|
||||||
WiFi.setHostname("loraprs");
|
WiFi.setHostname("loraprs");
|
||||||
|
@ -59,7 +69,21 @@ void LoraPrs::reconnectWifi() {
|
||||||
Serial.println("ok");
|
Serial.println("ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::setupLora(int loraFreq)
|
bool LoraPrs::reconnectAprsis() {
|
||||||
|
|
||||||
|
Serial.print("APRSIS connecting...");
|
||||||
|
|
||||||
|
if (!aprsisConn_.connect(aprsHost_.c_str(), aprsPort_)) {
|
||||||
|
Serial.println("Failed to connect to " + aprsHost_ + ":" + aprsPort_);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Serial.println("ok");
|
||||||
|
|
||||||
|
aprsisConn_.print(aprsLogin_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoraPrs::setupLora(int loraFreq, int bw, byte sf, byte cr, byte pwr, byte sync)
|
||||||
{
|
{
|
||||||
Serial.print("LoRa init...");
|
Serial.print("LoRa init...");
|
||||||
|
|
||||||
|
@ -69,11 +93,11 @@ void LoraPrs::setupLora(int loraFreq)
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
delay(500);
|
delay(500);
|
||||||
}
|
}
|
||||||
LoRa.setSyncWord(CfgSync);
|
LoRa.setSyncWord(sync);
|
||||||
LoRa.setSpreadingFactor(CfgSpread);
|
LoRa.setSpreadingFactor(sf);
|
||||||
LoRa.setSignalBandwidth(CfgBw);
|
LoRa.setSignalBandwidth(bw);
|
||||||
LoRa.setCodingRate4(CfgCodingRate);
|
LoRa.setCodingRate4(cr);
|
||||||
LoRa.setTxPower(CfgPower);
|
LoRa.setTxPower(pwr);
|
||||||
LoRa.enableCrc();
|
LoRa.enableCrc();
|
||||||
|
|
||||||
Serial.println("ok");
|
Serial.println("ok");
|
||||||
|
@ -81,7 +105,7 @@ void LoraPrs::setupLora(int loraFreq)
|
||||||
|
|
||||||
void LoraPrs::setupBt(const String &btName)
|
void LoraPrs::setupBt(const String &btName)
|
||||||
{
|
{
|
||||||
if (btName.length() != 0) {
|
if (isClient_) {
|
||||||
Serial.print("BT init " + btName + "...");
|
Serial.print("BT init " + btName + "...");
|
||||||
|
|
||||||
if (serialBt_.begin(btName)) {
|
if (serialBt_.begin(btName)) {
|
||||||
|
@ -96,111 +120,46 @@ void LoraPrs::setupBt(const String &btName)
|
||||||
|
|
||||||
void LoraPrs::loop()
|
void LoraPrs::loop()
|
||||||
{
|
{
|
||||||
if (WiFi.status() != WL_CONNECTED && wifiName_.length() != 0) {
|
if (!isClient_) {
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
reconnectWifi();
|
reconnectWifi();
|
||||||
}
|
}
|
||||||
|
if (!aprsisConn_.connected()) {
|
||||||
|
reconnectAprsis();
|
||||||
|
}
|
||||||
|
while (aprsisConn_.available() > 0) {
|
||||||
|
char c = aprsisConn_.read();
|
||||||
|
Serial.print(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (serialBt_.available()) {
|
if (serialBt_.available()) {
|
||||||
onBtReceived();
|
onBtDataAvailable();
|
||||||
}
|
}
|
||||||
if (int packetSize = LoRa.parsePacket()) {
|
if (int packetSize = LoRa.parsePacket()) {
|
||||||
onLoraReceived(packetSize);
|
onLoraDataAvailable(packetSize);
|
||||||
}
|
}
|
||||||
delay(10);
|
delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::onAprsReceived(const String &aprsMessage)
|
void LoraPrs::onRfAprsReceived(const String &aprsMessage)
|
||||||
{
|
{
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
if (isClient_) return;
|
||||||
WiFiClient wifiClient;
|
|
||||||
|
|
||||||
if (!wifiClient.connect(CfgAprsHost.c_str(), CfgAprsPort)) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
Serial.println("Failed to connect to " + CfgAprsHost + ":" + CfgAprsPort);
|
reconnectWifi();
|
||||||
return;
|
}
|
||||||
|
if (!aprsisConn_.connected()) {
|
||||||
|
reconnectAprsis();
|
||||||
}
|
}
|
||||||
wifiClient.print(aprsLogin_);
|
|
||||||
Serial.print(aprsMessage);
|
Serial.print(aprsMessage);
|
||||||
wifiClient.print(aprsMessage);
|
aprsisConn_.print(aprsMessage);
|
||||||
wifiClient.stop();
|
|
||||||
}
|
if (!persistentConn_) {
|
||||||
else {
|
aprsisConn_.stop();
|
||||||
Serial.println("Wifi not connected, not sent");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String LoraPrs::decodeCall(byte *rxPtr)
|
void LoraPrs::onLoraDataAvailable(int packetSize)
|
||||||
{
|
|
||||||
byte callsign[7];
|
|
||||||
char ssid;
|
|
||||||
|
|
||||||
byte *ptr = rxPtr;
|
|
||||||
|
|
||||||
memset(callsign, 0, sizeof(callsign));
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
char c = *(ptr++) >> 1;
|
|
||||||
callsign[i] = (c == ' ') ? '\0' : c;
|
|
||||||
}
|
|
||||||
callsign[6] = '\0';
|
|
||||||
ssid = (*ptr >> 1);
|
|
||||||
|
|
||||||
String result = String((char*)callsign);
|
|
||||||
if (result.length() > 0 && ssid >= '0' && ssid <= '9') {
|
|
||||||
result += String("-") + String(ssid);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
String LoraPrs::convertAX25ToAprs(byte *rxPayload, int payloadLength, const String &signalReport)
|
|
||||||
{
|
|
||||||
byte *rxPtr = rxPayload;
|
|
||||||
String srcCall, dstCall, rptFirst, rptSecond, result;
|
|
||||||
|
|
||||||
dstCall = decodeCall(rxPtr);
|
|
||||||
rxPtr += 7;
|
|
||||||
|
|
||||||
srcCall = decodeCall(rxPtr);
|
|
||||||
rxPtr += 7;
|
|
||||||
|
|
||||||
if ((rxPayload[13] & 1) == 0) {
|
|
||||||
rptFirst = decodeCall(rxPtr);
|
|
||||||
rxPtr += 7;
|
|
||||||
|
|
||||||
if ((rxPayload[20] & 1) == 0) {
|
|
||||||
rptSecond = decodeCall(rxPtr);
|
|
||||||
rxPtr += 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(rxPtr++) != AX25Ctrl::UI) return result;
|
|
||||||
if (*(rxPtr++) != AX25Pid::NoLayer3) return result;
|
|
||||||
|
|
||||||
result += srcCall + String(">") + dstCall;
|
|
||||||
|
|
||||||
if (rptFirst.length() > 0) {
|
|
||||||
result += String(",") + rptFirst;
|
|
||||||
}
|
|
||||||
if (rptSecond.length() > 0) {
|
|
||||||
result += String(",") + rptSecond;
|
|
||||||
}
|
|
||||||
|
|
||||||
result += ":";
|
|
||||||
|
|
||||||
bool appendReport = ((char)*rxPtr == '=');
|
|
||||||
|
|
||||||
while (rxPtr < rxPayload + payloadLength) {
|
|
||||||
result += String((char)*(rxPtr++));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appendReport) {
|
|
||||||
result += signalReport;
|
|
||||||
}
|
|
||||||
|
|
||||||
result += "\n";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoraPrs::onLoraReceived(int packetSize)
|
|
||||||
{
|
{
|
||||||
int rxBufIndex = 0;
|
int rxBufIndex = 0;
|
||||||
byte rxBuf[packetSize];
|
byte rxBuf[packetSize];
|
||||||
|
@ -247,10 +206,10 @@ void LoraPrs::onLoraReceived(int packetSize)
|
||||||
LoRa.setFrequency(loraFreq_);
|
LoRa.setFrequency(loraFreq_);
|
||||||
}
|
}
|
||||||
|
|
||||||
String aprsMsg = convertAX25ToAprs(rxBuf, rxBufIndex, signalReport);
|
String aprsMsg = AX25::Payload(rxBuf, rxBufIndex).ToText(addSignalReport_ ? signalReport : String());
|
||||||
|
|
||||||
if (aprsMsg.length() != 0) {
|
if (aprsMsg.length() != 0) {
|
||||||
onAprsReceived(aprsMsg);
|
onRfAprsReceived(aprsMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(50);
|
delay(50);
|
||||||
|
@ -262,7 +221,7 @@ void LoraPrs::kissResetState()
|
||||||
kissState_ = KissState::Void;
|
kissState_ = KissState::Void;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::onBtReceived()
|
void LoraPrs::onBtDataAvailable()
|
||||||
{
|
{
|
||||||
while (serialBt_.available()) {
|
while (serialBt_.available()) {
|
||||||
byte txByte = serialBt_.read();
|
byte txByte = serialBt_.read();
|
||||||
|
|
83
loraprs.h
83
loraprs.h
|
@ -7,32 +7,61 @@
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
|
||||||
#include "BluetoothSerial.h"
|
#include "BluetoothSerial.h"
|
||||||
|
#include "aprsmsg.h"
|
||||||
|
|
||||||
|
class LoraPrsConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool IsClientMode;
|
||||||
|
|
||||||
|
long LoraFreq;
|
||||||
|
int LoraBw;
|
||||||
|
byte LoraSf;
|
||||||
|
byte LoraCodingRate;
|
||||||
|
byte LoraSync;
|
||||||
|
byte LoraPower;
|
||||||
|
|
||||||
|
int AprsPort;
|
||||||
|
String AprsHost;
|
||||||
|
String AprsLogin;
|
||||||
|
String AprsPass;
|
||||||
|
String AprsFilter;
|
||||||
|
|
||||||
|
String BtName;
|
||||||
|
|
||||||
|
String WifiSsid;
|
||||||
|
String WifiKey;
|
||||||
|
|
||||||
|
bool EnableSignalReport;
|
||||||
|
bool EnableAutoFreqCorrection;
|
||||||
|
bool EnablePersistentAprsConnection;
|
||||||
|
bool EnableIsToRf;
|
||||||
|
bool EnableRepeater;
|
||||||
|
};
|
||||||
|
|
||||||
class LoraPrs
|
class LoraPrs
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LoraPrs(long loraFreq, const String &btName, const String &wifiName, const String &wifiKey,
|
LoraPrs();
|
||||||
const String &aprsLoginCallsign, const String& aprsPass, bool autoCorrectFreq);
|
|
||||||
|
|
||||||
void setup();
|
void setup(const LoraPrsConfig &conf);
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupWifi(const String &wifiName, const String &wifiKey);
|
void setupWifi(const String &wifiName, const String &wifiKey);
|
||||||
void setupLora(int loraFreq);
|
void setupLora(int loraFreq, int bw, byte sf, byte cr, byte pwr, byte sync);
|
||||||
void setupBt(const String &btName);
|
void setupBt(const String &btName);
|
||||||
|
|
||||||
void reconnectWifi();
|
void reconnectWifi();
|
||||||
|
bool reconnectAprsis();
|
||||||
|
|
||||||
void onLoraReceived(int packetSize);
|
void onLoraDataAvailable(int packetSize);
|
||||||
void onBtReceived();
|
void onBtDataAvailable();
|
||||||
void onAprsReceived(const String & aprsMessage);
|
|
||||||
|
void onRfAprsReceived(const String &aprsMessage);
|
||||||
|
|
||||||
void kissResetState();
|
void kissResetState();
|
||||||
|
|
||||||
String convertAX25ToAprs(byte *rxPayload, int payloadLength, const String &signalReport);
|
|
||||||
String decodeCall(byte *rxPtr);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum KissMarker {
|
enum KissMarker {
|
||||||
Fend = 0xc0,
|
Fend = 0xc0,
|
||||||
|
@ -53,43 +82,31 @@ private:
|
||||||
NoCmd = 0x80
|
NoCmd = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AX25Ctrl {
|
|
||||||
UI = 0x03
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AX25Pid {
|
|
||||||
NoLayer3 = 0xf0
|
|
||||||
};
|
|
||||||
|
|
||||||
const String CfgLoraprsVersion = "LoRAPRS 0.1";
|
const String CfgLoraprsVersion = "LoRAPRS 0.1";
|
||||||
|
|
||||||
const byte CfgPinSs = 5;
|
const byte CfgPinSs = 5;
|
||||||
const byte CfgPinRst = 26;
|
const byte CfgPinRst = 26;
|
||||||
const byte CfgPinDio0 = 14;
|
const byte CfgPinDio0 = 14;
|
||||||
|
|
||||||
const int CfgBw = 125e3;
|
|
||||||
const byte CfgSpread = 12;
|
|
||||||
//const int CfgBw = 20e3;
|
|
||||||
//const byte CfgSpread = 9;
|
|
||||||
const byte CfgCodingRate = 7;
|
|
||||||
const byte CfgSync = 0xf3;
|
|
||||||
const byte CfgPower = 20;
|
|
||||||
|
|
||||||
const int CfgAprsPort = 14580;
|
|
||||||
const String CfgAprsHost = "rotate.aprs2.net";
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool isClient_;
|
||||||
long loraFreq_;
|
long loraFreq_;
|
||||||
bool autoCorrectFreq_;
|
|
||||||
String btName_;
|
String aprsHost_;
|
||||||
String wifiName_;
|
int aprsPort_;
|
||||||
String wifiKey_;
|
|
||||||
String aprsLogin_;
|
String aprsLogin_;
|
||||||
|
|
||||||
|
bool autoCorrectFreq_;
|
||||||
|
bool addSignalReport_;
|
||||||
|
bool persistentConn_;
|
||||||
|
bool enableIsToRf_;
|
||||||
|
bool enableRepeater_;
|
||||||
|
|
||||||
KissCmd kissCmd_;
|
KissCmd kissCmd_;
|
||||||
KissState kissState_;
|
KissState kissState_;
|
||||||
|
|
||||||
BluetoothSerial serialBt_;
|
BluetoothSerial serialBt_;
|
||||||
|
WiFiClient aprsisConn_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LORAPRS_H
|
#endif // LORAPRS_H
|
||||||
|
|
Ładowanie…
Reference in New Issue