kopia lustrzana https://github.com/sh123/esp32_loraprs
Refactor callsign management into separate module and add support for baseic WIDEn-n digirepating
rodzic
c042747fff
commit
9c06c93ec0
|
@ -0,0 +1,141 @@
|
||||||
|
#include "ax25_callsign.h"
|
||||||
|
|
||||||
|
namespace AX25 {
|
||||||
|
|
||||||
|
Callsign::Callsign()
|
||||||
|
: isValid_(false)
|
||||||
|
, call_()
|
||||||
|
, ssid_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Callsign::Callsign(const Callsign &callsign)
|
||||||
|
: isValid_(callsign.isValid_)
|
||||||
|
, call_(callsign.call_)
|
||||||
|
, ssid_(callsign.ssid_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Callsign& Callsign::operator=(const Callsign &callsign)
|
||||||
|
{
|
||||||
|
isValid_ = callsign.isValid_;
|
||||||
|
call_ = callsign.call_;
|
||||||
|
ssid_ = callsign.ssid_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Callsign::Callsign(const byte *rxPayload, int payloadLength)
|
||||||
|
: isValid_(false)
|
||||||
|
, call_()
|
||||||
|
, ssid_(0)
|
||||||
|
{
|
||||||
|
isValid_ = fromBinary(rxPayload, payloadLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Callsign::Callsign(String callsign)
|
||||||
|
: isValid_(false)
|
||||||
|
, call_()
|
||||||
|
, ssid_(0)
|
||||||
|
{
|
||||||
|
isValid_ = fromString(callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Callsign::ToBinary(byte *txPayload, int bufferLength) const
|
||||||
|
{
|
||||||
|
return encode(txPayload, bufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
String Callsign::ToString() const
|
||||||
|
{
|
||||||
|
String result = call_;
|
||||||
|
if (ssid_ != 0) {
|
||||||
|
result += "-" + String(ssid_);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Callsign::Digirepeat(const String &ownCallsign)
|
||||||
|
{
|
||||||
|
// only WIDE supported
|
||||||
|
if (call_.startsWith("WIDE*")) return false;
|
||||||
|
if (call_.startsWith("WIDE") && call_.length() >= 5) {
|
||||||
|
char wideLevel = call_.charAt(4);
|
||||||
|
if ((wideLevel == '1' || wideLevel == '2' || wideLevel == '3') && ssid_ > 0) {
|
||||||
|
if (--ssid_ == 0) {
|
||||||
|
call_ += "*";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Callsign::encode(byte *txPtr, int bufferLength) const
|
||||||
|
{
|
||||||
|
if (bufferLength < CallsignSize) return false;
|
||||||
|
|
||||||
|
byte *ptr = txPtr;
|
||||||
|
|
||||||
|
memset(ptr, 0, bufferLength);
|
||||||
|
|
||||||
|
for (int i = 0; i < CallsignSize - 1; i++) {
|
||||||
|
if (i < call_.length()) {
|
||||||
|
char c = call_.charAt(i);
|
||||||
|
*(ptr++) = c << 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*(ptr++) = char(' ') << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(txPtr + CallsignSize - 1) = ssid_ << 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Callsign::fromString(String callsign)
|
||||||
|
{
|
||||||
|
// "ABCDEF-XX"
|
||||||
|
if (callsign.length() > CallsignSize + 2 || callsign.length() == 0) return false;
|
||||||
|
|
||||||
|
int delimIndex = callsign.indexOf('-');
|
||||||
|
// "ABCDEF-"
|
||||||
|
if (delimIndex = callsign.length() - 1) return false;
|
||||||
|
|
||||||
|
call_ = callsign;
|
||||||
|
ssid_ = 0;
|
||||||
|
|
||||||
|
if (delimIndex == -1) {
|
||||||
|
// "ABCDEFG"
|
||||||
|
if (callsign.length() >= CallsignSize) return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
call_ = callsign.substring(0, delimIndex);
|
||||||
|
ssid_ = callsign.substring(delimIndex + 1).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Callsign::fromBinary(const byte *rxPtr, int length)
|
||||||
|
{
|
||||||
|
if (length < CallsignSize) return false;
|
||||||
|
|
||||||
|
byte callsign[CallsignSize];
|
||||||
|
|
||||||
|
const byte *ptr = rxPtr;
|
||||||
|
|
||||||
|
memset(callsign, 0, sizeof(callsign));
|
||||||
|
|
||||||
|
for (int i = 0; i < CallsignSize - 1; i++) {
|
||||||
|
char c = *(ptr++) >> 1;
|
||||||
|
callsign[i] = (c == ' ') ? '\0' : c;
|
||||||
|
}
|
||||||
|
callsign[CallsignSize-1] = '\0';
|
||||||
|
|
||||||
|
ssid_ = (*ptr >> 1) & 0x0f;
|
||||||
|
call_ = String((char*)callsign);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AX25
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef AX25_CALLSIGN_H
|
||||||
|
#define AX25_CALLSIGN_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
namespace AX25 {
|
||||||
|
|
||||||
|
class Callsign
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Callsign();
|
||||||
|
Callsign(const Callsign &callsign);
|
||||||
|
Callsign& operator=(const Callsign &callsign);
|
||||||
|
|
||||||
|
Callsign(const byte *rxPayload, int payloadLength);
|
||||||
|
Callsign(String inputText);
|
||||||
|
|
||||||
|
inline bool IsValid() const { return isValid_; };
|
||||||
|
|
||||||
|
String ToString() const;
|
||||||
|
bool ToBinary(byte *txPayload, int bufferLength) const;
|
||||||
|
|
||||||
|
bool Digirepeat(const String &ownCallsign);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool encode(byte *txPtr, int bufferLength) const;
|
||||||
|
|
||||||
|
bool fromString(String callsign);
|
||||||
|
bool fromBinary(const byte *rxPtr, int payloadLength);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int CallsignSize = 7;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isValid_;
|
||||||
|
String call_;
|
||||||
|
byte ssid_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // AX25
|
||||||
|
|
||||||
|
#endif // APRSMSG_H
|
104
ax25_payload.cpp
104
ax25_payload.cpp
|
@ -5,47 +5,47 @@ namespace AX25 {
|
||||||
Payload::Payload(byte *rxPayload, int payloadLength)
|
Payload::Payload(byte *rxPayload, int payloadLength)
|
||||||
: rptCallsCount_(0)
|
: rptCallsCount_(0)
|
||||||
{
|
{
|
||||||
isValid_ = parsePayload(rxPayload, payloadLength);
|
isValid_ = fromBinary(rxPayload, payloadLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
Payload::Payload(String inputText)
|
Payload::Payload(String inputText)
|
||||||
: rptCallsCount_(0)
|
: rptCallsCount_(0)
|
||||||
{
|
{
|
||||||
isValid_ = parseString(inputText);
|
isValid_ = fromString(inputText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Payload::Dump()
|
void Payload::Dump()
|
||||||
{
|
{
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.print("valid: "); Serial.println(isValid_);
|
Serial.print("valid: "); Serial.println(isValid_);
|
||||||
Serial.println("src: " + srcCall_);
|
Serial.println("src: " + srcCall_.ToString());
|
||||||
Serial.println("dst: " + dstCall_);
|
Serial.println("dst: " + dstCall_.ToString());
|
||||||
Serial.print("rpt: ");
|
Serial.print("rpt: ");
|
||||||
for (int i = 0; i < rptCallsCount_; i++) {
|
for (int i = 0; i < rptCallsCount_; i++) {
|
||||||
Serial.print(rptCalls_[i] + " ");
|
Serial.print(rptCalls_[i].ToString() + " ");
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.println("info: " + info_);
|
Serial.println("info: " + info_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Payload::ToBinary(byte *txPayload, int bufferLength)
|
int Payload::ToBinary(byte *txPayload, int bufferLength) const
|
||||||
{
|
{
|
||||||
byte *txPtr = txPayload;
|
byte *txPtr = txPayload;
|
||||||
byte *txEnd = txPayload + bufferLength;
|
byte *txEnd = txPayload + bufferLength;
|
||||||
|
|
||||||
// destination address
|
// destination address
|
||||||
if (!encodeCall(dstCall_, txPtr, CallsignSize)) return 0;
|
if (!dstCall_.ToBinary(txPtr, CallsignSize)) return 0;
|
||||||
txPtr += CallsignSize;
|
txPtr += CallsignSize;
|
||||||
if (txPtr >= txEnd) return 0;
|
if (txPtr >= txEnd) return 0;
|
||||||
|
|
||||||
// source address
|
// source address
|
||||||
if (!encodeCall(srcCall_, txPtr, CallsignSize)) return 0;
|
if (!srcCall_.ToBinary(txPtr, CallsignSize)) return 0;
|
||||||
txPtr += CallsignSize;
|
txPtr += CallsignSize;
|
||||||
if (txPtr >= txEnd) return 0;
|
if (txPtr >= txEnd) return 0;
|
||||||
|
|
||||||
// digipeater addresses
|
// digipeater addresses
|
||||||
for (int i = 0; i < rptCallsCount_; i++) {
|
for (int i = 0; i < rptCallsCount_; i++) {
|
||||||
if (!encodeCall(rptCalls_[i], txPtr, CallsignSize)) return 0;
|
if (!rptCalls_[i].ToBinary(txPtr, CallsignSize)) return 0;
|
||||||
txPtr += CallsignSize;
|
txPtr += CallsignSize;
|
||||||
if (txPtr >= txEnd) return 0;
|
if (txPtr >= txEnd) return 0;
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,13 @@ int Payload::ToBinary(byte *txPayload, int bufferLength)
|
||||||
return (int)(txPtr-txPayload);
|
return (int)(txPtr-txPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Payload::ToText(String customComment)
|
String Payload::ToString(String customComment)
|
||||||
{
|
{
|
||||||
String txt = srcCall_ + String(">") + dstCall_;
|
String txt = srcCall_.ToString() + String(">") + dstCall_.ToString();
|
||||||
|
|
||||||
for (int i = 0; i < rptCallsCount_; i++) {
|
for (int i = 0; i < rptCallsCount_; i++) {
|
||||||
if (rptCalls_[i].length() > 0) {
|
if (rptCalls_[i].IsValid()) {
|
||||||
txt += String(",") + rptCalls_[i];
|
txt += String(",") + rptCalls_[i].ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,18 +86,30 @@ String Payload::ToText(String customComment)
|
||||||
return txt + String("\n");
|
return txt + String("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Payload::parsePayload(const byte *rxPayload, int payloadLength)
|
bool Payload::Digirepeat(const String &ownCallsign)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < rptCallsCount_; i++) {
|
||||||
|
if (rptCalls_[i].Digirepeat(ownCallsign)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Payload::fromBinary(const byte *rxPayload, int payloadLength)
|
||||||
{
|
{
|
||||||
const byte *rxPtr = rxPayload;
|
const byte *rxPtr = rxPayload;
|
||||||
const byte *rxEnd = rxPayload + payloadLength;
|
const byte *rxEnd = rxPayload + payloadLength;
|
||||||
|
|
||||||
|
if (payloadLength < CallsignSize) return false;
|
||||||
|
|
||||||
// destination address
|
// destination address
|
||||||
dstCall_ = decodeCall(rxPtr);
|
dstCall_ = AX25::Callsign(rxPtr, CallsignSize);
|
||||||
rxPtr += CallsignSize;
|
rxPtr += CallsignSize;
|
||||||
if (rxPtr >= rxEnd) return false;
|
if (rxPtr >= rxEnd) return false;
|
||||||
|
|
||||||
// source address
|
// source address
|
||||||
srcCall_ = decodeCall(rxPtr);
|
srcCall_ = AX25::Callsign(rxPtr, CallsignSize);
|
||||||
rxPtr += CallsignSize;
|
rxPtr += CallsignSize;
|
||||||
if (rxPtr >= rxEnd) return false;
|
if (rxPtr >= rxEnd) return false;
|
||||||
|
|
||||||
|
@ -106,7 +118,7 @@ bool Payload::parsePayload(const byte *rxPayload, int payloadLength)
|
||||||
// digipeater addresses
|
// digipeater addresses
|
||||||
for (int i = 0; i < RptMaxCount; i++) {
|
for (int i = 0; i < RptMaxCount; i++) {
|
||||||
if ((rxPayload[(i + 2) * CallsignSize - 1] & 1) == 0) {
|
if ((rxPayload[(i + 2) * CallsignSize - 1] & 1) == 0) {
|
||||||
rptCalls_[i] = decodeCall(rxPtr);
|
rptCalls_[i] = AX25::Callsign(rxPtr, CallsignSize);
|
||||||
rptCallsCount_++;
|
rptCallsCount_++;
|
||||||
rxPtr += CallsignSize;
|
rxPtr += CallsignSize;
|
||||||
if (rxPtr >= rxEnd) return false;
|
if (rxPtr >= rxEnd) return false;
|
||||||
|
@ -129,7 +141,7 @@ bool Payload::parsePayload(const byte *rxPayload, int payloadLength)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Payload::parseString(String inputText)
|
bool Payload::fromString(String inputText)
|
||||||
{
|
{
|
||||||
int rptIndex = inputText.indexOf('>');
|
int rptIndex = inputText.indexOf('>');
|
||||||
int infoIndex = inputText.indexOf(':');
|
int infoIndex = inputText.indexOf(':');
|
||||||
|
@ -160,60 +172,4 @@ bool Payload::parseString(String inputText)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Payload::encodeCall(String inputText, byte *txPtr, int bufferLength)
|
|
||||||
{
|
|
||||||
if (bufferLength < CallsignSize) return false;
|
|
||||||
|
|
||||||
String callsign = inputText;
|
|
||||||
byte ssid = 0;
|
|
||||||
|
|
||||||
int delimIndex = inputText.indexOf('-');
|
|
||||||
if (delimIndex + 1 >= inputText.length()) return false;
|
|
||||||
|
|
||||||
if (delimIndex != -1) {
|
|
||||||
callsign = inputText.substring(0, delimIndex);
|
|
||||||
ssid = inputText.substring(delimIndex + 1).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte *ptr = txPtr;
|
|
||||||
|
|
||||||
memset(ptr, 0, bufferLength);
|
|
||||||
|
|
||||||
for (int i = 0; i < CallsignSize - 1; i++) {
|
|
||||||
if (i < callsign.length()) {
|
|
||||||
char c = callsign.charAt(i);
|
|
||||||
*(ptr++) = c << 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*(ptr++) = char(' ') << 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*(txPtr + CallsignSize - 1) = ssid << 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String Payload::decodeCall(const byte *rxPtr)
|
|
||||||
{
|
|
||||||
byte callsign[CallsignSize];
|
|
||||||
|
|
||||||
const byte *ptr = rxPtr;
|
|
||||||
|
|
||||||
memset(callsign, 0, sizeof(callsign));
|
|
||||||
|
|
||||||
for (int i = 0; i < CallsignSize - 1; i++) {
|
|
||||||
char c = *(ptr++) >> 1;
|
|
||||||
callsign[i] = (c == ' ') ? '\0' : c;
|
|
||||||
}
|
|
||||||
callsign[CallsignSize-1] = '\0';
|
|
||||||
byte ssid = (*ptr >> 1) & 0x0f;
|
|
||||||
|
|
||||||
String result = String((char*)callsign);
|
|
||||||
|
|
||||||
if (result.length() > 0 && ssid != 0) {
|
|
||||||
result += String("-") + String(ssid);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // AX25
|
} // AX25
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#ifndef APRSMSG_H
|
#ifndef AX25_PAYLOAD_H
|
||||||
#define APRSMSG_H
|
#define AX25_PAYLOAD_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "ax25_callsign.h"
|
||||||
|
|
||||||
namespace AX25 {
|
namespace AX25 {
|
||||||
|
|
||||||
class Payload
|
class Payload
|
||||||
|
@ -13,17 +15,15 @@ public:
|
||||||
|
|
||||||
inline bool IsValid() const { return isValid_; }
|
inline bool IsValid() const { return isValid_; }
|
||||||
|
|
||||||
String ToText(String customComment);
|
String ToString(String customComment);
|
||||||
int ToBinary(byte *txPayload, int bufferLength);
|
int ToBinary(byte *txPayload, int bufferLength) const;
|
||||||
|
|
||||||
|
bool Digirepeat(const String &ownCallsign);
|
||||||
void Dump();
|
void Dump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String decodeCall(const byte *rxPtr);
|
bool fromString(String inputText);
|
||||||
bool encodeCall(String callsign, byte *txPtr, int bufferLength);
|
bool fromBinary(const byte *rxPayload, int payloadLength);
|
||||||
|
|
||||||
bool parseString(String inputText);
|
|
||||||
bool parsePayload(const byte *rxPayload, int payloadLength);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum AX25Ctrl {
|
enum AX25Ctrl {
|
||||||
|
@ -39,8 +39,8 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isValid_;
|
bool isValid_;
|
||||||
String srcCall_, dstCall_;
|
Callsign srcCall_, dstCall_;
|
||||||
String rptCalls_[7];
|
Callsign rptCalls_[7];
|
||||||
int rptCallsCount_;
|
int rptCallsCount_;
|
||||||
String info_;
|
String info_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,7 @@ void initializeConfig() {
|
||||||
cfg.EnableSignalReport = true;
|
cfg.EnableSignalReport = true;
|
||||||
cfg.EnableAutoFreqCorrection = true;
|
cfg.EnableAutoFreqCorrection = true;
|
||||||
cfg.EnablePersistentAprsConnection = true;
|
cfg.EnablePersistentAprsConnection = true;
|
||||||
|
cfg.EnableRfToIs = true;
|
||||||
cfg.EnableIsToRf = false;
|
cfg.EnableIsToRf = false;
|
||||||
cfg.EnableRepeater = false;
|
cfg.EnableRepeater = false;
|
||||||
}
|
}
|
||||||
|
|
44
loraprs.cpp
44
loraprs.cpp
|
@ -11,6 +11,7 @@ void LoraPrs::setup(const LoraPrsConfig &conf)
|
||||||
{
|
{
|
||||||
isClient_ = conf.IsClientMode;
|
isClient_ = conf.IsClientMode;
|
||||||
loraFreq_ = conf.LoraFreq;
|
loraFreq_ = conf.LoraFreq;
|
||||||
|
ownCallsign_ = conf.AprsLogin;
|
||||||
|
|
||||||
aprsLogin_ = String("user ") + conf.AprsLogin + String(" pass ") +
|
aprsLogin_ = String("user ") + conf.AprsLogin + String(" pass ") +
|
||||||
conf.AprsPass + String(" vers ") + CfgLoraprsVersion;
|
conf.AprsPass + String(" vers ") + CfgLoraprsVersion;
|
||||||
|
@ -25,6 +26,7 @@ void LoraPrs::setup(const LoraPrsConfig &conf)
|
||||||
autoCorrectFreq_ = conf.EnableAutoFreqCorrection;
|
autoCorrectFreq_ = conf.EnableAutoFreqCorrection;
|
||||||
addSignalReport_ = conf.EnableSignalReport;
|
addSignalReport_ = conf.EnableSignalReport;
|
||||||
persistentConn_ = conf.EnablePersistentAprsConnection;
|
persistentConn_ = conf.EnablePersistentAprsConnection;
|
||||||
|
enableRfToIs_ = conf.EnableRfToIs;
|
||||||
enableIsToRf_ = conf.EnableIsToRf;
|
enableIsToRf_ = conf.EnableIsToRf;
|
||||||
enableRepeater_ = conf.EnableRepeater;
|
enableRepeater_ = conf.EnableRepeater;
|
||||||
|
|
||||||
|
@ -140,12 +142,8 @@ void LoraPrs::loop()
|
||||||
delay(10);
|
delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::onRfAprsReceived(String aprsMessage)
|
void LoraPrs::sendToAprsis(String aprsMessage)
|
||||||
{
|
{
|
||||||
Serial.print(aprsMessage);
|
|
||||||
|
|
||||||
if (isClient_) return;
|
|
||||||
|
|
||||||
if (WiFi.status() != WL_CONNECTED) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
reconnectWifi();
|
reconnectWifi();
|
||||||
}
|
}
|
||||||
|
@ -173,24 +171,28 @@ void LoraPrs::onAprsisDataAvailable()
|
||||||
|
|
||||||
if (enableIsToRf_ && aprsisData.length() > 0) {
|
if (enableIsToRf_ && aprsisData.length() > 0) {
|
||||||
AX25::Payload payload(aprsisData);
|
AX25::Payload payload(aprsisData);
|
||||||
|
sendToLora(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (payload.IsValid()) {
|
bool LoraPrs::sendToLora(const AX25::Payload &payload)
|
||||||
|
{
|
||||||
|
if (!payload.IsValid()) {
|
||||||
|
Serial.println("Invalid payload from APRSIS");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
byte buf[512];
|
byte buf[512];
|
||||||
int bytesWritten = payload.ToBinary(buf, sizeof(buf));
|
int bytesWritten = payload.ToBinary(buf, sizeof(buf));
|
||||||
if (bytesWritten > 0) {
|
if (bytesWritten <= 0) {
|
||||||
|
Serial.println("Failed to serialize payload");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
LoRa.beginPacket();
|
LoRa.beginPacket();
|
||||||
LoRa.write(buf, bytesWritten);
|
LoRa.write(buf, bytesWritten);
|
||||||
LoRa.endPacket(true);
|
LoRa.endPacket(true);
|
||||||
}
|
return true;
|
||||||
else {
|
|
||||||
Serial.println("Failed to serialize payload");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Serial.println("Invalid payload from APRSIS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraPrs::onLoraDataAvailable(int packetSize)
|
void LoraPrs::onLoraDataAvailable(int packetSize)
|
||||||
|
@ -243,7 +245,15 @@ void LoraPrs::onLoraDataAvailable(int packetSize)
|
||||||
AX25::Payload payload(rxBuf, rxBufIndex);
|
AX25::Payload payload(rxBuf, rxBufIndex);
|
||||||
|
|
||||||
if (payload.IsValid()) {
|
if (payload.IsValid()) {
|
||||||
onRfAprsReceived(payload.ToText(addSignalReport_ ? signalReport : String()));
|
String textPayload = payload.ToString(addSignalReport_ ? signalReport : String());
|
||||||
|
Serial.print(textPayload);
|
||||||
|
|
||||||
|
if (enableRfToIs_ && !isClient_) {
|
||||||
|
sendToAprsis(textPayload);
|
||||||
|
}
|
||||||
|
if (enableRepeater_ && payload.Digirepeat(ownCallsign_)) {
|
||||||
|
sendToLora(payload);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Serial.println("Invalid payload from LoRA");
|
Serial.println("Invalid payload from LoRA");
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct LoraPrsConfig
|
||||||
bool EnableSignalReport;
|
bool EnableSignalReport;
|
||||||
bool EnableAutoFreqCorrection;
|
bool EnableAutoFreqCorrection;
|
||||||
bool EnablePersistentAprsConnection;
|
bool EnablePersistentAprsConnection;
|
||||||
|
bool EnableRfToIs;
|
||||||
bool EnableIsToRf;
|
bool EnableIsToRf;
|
||||||
bool EnableRepeater;
|
bool EnableRepeater;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +59,8 @@ private:
|
||||||
void onBtDataAvailable();
|
void onBtDataAvailable();
|
||||||
void onAprsisDataAvailable();
|
void onAprsisDataAvailable();
|
||||||
|
|
||||||
void onRfAprsReceived(String aprsMessage);
|
void sendToAprsis(String aprsMessage);
|
||||||
|
bool sendToLora(const AX25::Payload &payload);
|
||||||
|
|
||||||
void kissResetState();
|
void kissResetState();
|
||||||
|
|
||||||
|
@ -83,6 +85,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
const String CfgLoraprsVersion = "LoRAPRS 0.1";
|
const String CfgLoraprsVersion = "LoRAPRS 0.1";
|
||||||
|
const String CfgAprsSoftware = "APZLRA";
|
||||||
|
|
||||||
const byte CfgPinSs = 5;
|
const byte CfgPinSs = 5;
|
||||||
const byte CfgPinRst = 26;
|
const byte CfgPinRst = 26;
|
||||||
|
@ -92,6 +95,8 @@ private:
|
||||||
bool isClient_;
|
bool isClient_;
|
||||||
long loraFreq_;
|
long loraFreq_;
|
||||||
|
|
||||||
|
String ownCallsign_;
|
||||||
|
|
||||||
String aprsHost_;
|
String aprsHost_;
|
||||||
int aprsPort_;
|
int aprsPort_;
|
||||||
String aprsLogin_;
|
String aprsLogin_;
|
||||||
|
@ -99,6 +104,7 @@ private:
|
||||||
bool autoCorrectFreq_;
|
bool autoCorrectFreq_;
|
||||||
bool addSignalReport_;
|
bool addSignalReport_;
|
||||||
bool persistentConn_;
|
bool persistentConn_;
|
||||||
|
bool enableRfToIs_;
|
||||||
bool enableIsToRf_;
|
bool enableIsToRf_;
|
||||||
bool enableRepeater_;
|
bool enableRepeater_;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue