Separate APRS and PACKET mode sources

KISS_TNC
US1GHQ 2021-09-07 13:44:17 +03:00
parent b0bdfaae44
commit 5990975d34
6 changed files with 159 additions and 32 deletions

View File

@ -1,5 +1,6 @@
#include <Arduino.h>
#include <KISS_TO_TNC2.h>
#include <KISS_TO_PKT.h>
#if defined(ENABLE_BLUETOOTH)
#include "BluetoothSerial.h"

View File

@ -1,10 +1,10 @@
#ifndef BUILD_NUMBER
#define BUILD_NUMBER "28"
#define BUILD_NUMBER "86"
#endif
#ifndef VERSION
#define VERSION "v0.3.2.28- - 2021-09-06 23:22:02.459488"
#define VERSION "v0.3.2.86-b0bdfaa - 2021-09-07 13:41:47.140024"
#endif
#ifndef VERSION_SHORT
#define VERSION_SHORT "v0.3.2.28-"
#define VERSION_SHORT "v0.3.2.86-b0bdfaa"
#endif

View File

@ -0,0 +1,116 @@
#include "KISS_TO_PKT.h"
bool validateTNC2Frame(const String &tnc2FormattedFrame);
bool validateKISSFrame(const String &kissFormattedFrame);
String decapsulateKISS(const String &frame);
/*
* https://ham.zmailer.org/oh2mqk/aprx/PROTOCOLS
After successfull login, communication carries "TNC2" format
APRS messages. Namely text encoding of AX.25 UI frames in
what became known as "TNC2 monitor style":
SOURCE>DESTIN:payload
SOURCE>DESTIN,VIA,VIA:payload
The SOURCE, DESTIN, and VIA fields are AX.25 address fields,
and have "-SSID" value annexed if the SSID is not zero.
Also in VIA-fields, if the "HAS BEEN DIGIPEATED" bit is set
(AX.25 v2 protocol feature) a star ('*') character is appended.
VIA-fields are separated by comma (',') from DESTIN, and each
other.
A double-colon (':') separates address data from payload.
The payload is passed _AS_IS_ without altering any message
content bytes, however ending at first CR or LF character
encountered in the packet.
*/
//HACK for working Packet mode
String encode_kiss_pkt(const String &tnc2FormattedFrame)
{
String TNC2Frame = "";
String ax25Frame = encapsulateKISS(tnc2FormattedFrame, CMD_DATA);
TNC2Frame += ax25Frame;
return TNC2Frame;
}
String encapsulateKISS(const String &ax25Frame, uint8_t TNCCmd)
{
String kissFrame = "";
kissFrame += (char) FEND; // start of frame
kissFrame += (char) (0x0f & TNCCmd); // TNC0, cmd
for (int i = 0; i < ax25Frame.length(); ++i)
{
char currentChar = ax25Frame.charAt(i);
if (currentChar == (char) FEND)
{
kissFrame += (char) FESC;
kissFrame += (char) TFEND;
}
else if (currentChar == (char) FESC)
{
kissFrame += (char) FESC;
kissFrame += (char) TFESC;
}
else
{
kissFrame += currentChar;
}
}
kissFrame += (char) FEND; // end of frame
return kissFrame;
}
String decapsulateKISS(const String &frame, uint8_t TNCCmd)
{
String ax25Frame = "";
ax25Frame += (char) FEND; // start of frame
ax25Frame += (char) (TNCCmd); // TNC0, cmd
for (int i = 2; i < frame.length() - 1; ++i)
{
char currentChar = frame.charAt(i);
if (currentChar == (char) FEND)
{
ax25Frame += (char) FESC;
ax25Frame += (char) TFEND;
}
else if (currentChar == (char) FESC)
{
ax25Frame += (char) FESC;
ax25Frame += (char) TFESC;
}
else
{
ax25Frame += currentChar;
}
}
ax25Frame += (char) FEND; // end of frame
Serial.print(ax25Frame);
return ax25Frame;
}
//HACK for PACKEt MODE
String decode_kiss_pkt(const String &inputKISSTNCFrame, bool &dataFrame) {
String TNC2Frame = "";
dataFrame = inputKISSTNCFrame.charAt(1) == CMD_DATA;
if (dataFrame){
String ax25Frame = decapsulateKISS(inputKISSTNCFrame, CMD_DATA);
delay(250);
TNC2Frame += ax25Frame;
}
return TNC2Frame;
}
bool validateTNC2Frame(const String &tnc2FormattedFrame) {
return (tnc2FormattedFrame.indexOf(':') != -1) &&
(tnc2FormattedFrame.indexOf('>') != -1);
}
bool validateKISSFrame(const String &kissFormattedFrame) {
return kissFormattedFrame.charAt(0) == (char) FEND &&
kissFormattedFrame.charAt(kissFormattedFrame.length() - 1) == (char) FEND;
}

View File

@ -0,0 +1,32 @@
#include <Arduino.h>
#include "KISS.h"
#define APRS_CONTROL_FIELD 0xf0
#define APRS_INFORMATION_FIELD 0xf0
#define HAS_BEEN_DIGIPITED_MASK 0b10000000
#define IS_LAST_ADDRESS_POSITION_MASK 0b1
//Data control frames, ported from Direwolf
//U-Frames
#define U_SABME 0x6f
#define U_SABM 0x3f //ok
#define U_DISC 0x53 //ok
#define U_DM 0x1f //need test
#define U_UA 0x73 //ok
#define U_FRMR 0x97 //need test
#define U_UI 0x13 //need test
#define U_XID 0xbf //need test
#define U_TEST 0xf3 //need test
//S-Frames
#define S_RR 0x11 //need test
#define S_RNR 0x15 //need test
#define S_REJ 0x19 //need test
#define S_SREJ 0x1d //need test
//I-Frame
#define I_I 0xff //need test
//END
//PACKET MODE
String encode_kiss_pkt(const String& tnc2FormattedFrame);
String decode_kiss_pkt(const String &inputKISSTNCFrame, bool &dataFrame);
String encapsulateKISS(const String &ax25Frame, uint8_t TNCCmd);

View File

@ -66,15 +66,6 @@ String encode_kiss(const String &tnc2FormattedFrame) {
return kissFrame;
}
//HACK for working Packet mode
String encode_kiss_pkt(const String &tnc2FormattedFrame)
{
String TNC2Frame = "";
String ax25Frame = encapsulateKISS(tnc2FormattedFrame, CMD_DATA);
TNC2Frame += ax25Frame;
return TNC2Frame;
}
String encapsulateKISS(const String &ax25Frame, uint8_t TNCCmd)
{
String kissFrame = "";
@ -163,16 +154,6 @@ String decode_kiss(const String &inputKISSTNCFrame, bool &dataFrame) {
return TNC2Frame;
}
//HACK for PACKEt MODE
String decode_kiss_pkt(const String &inputKISSTNCFrame, bool &dataFrame) {
String TNC2Frame = "";
dataFrame = inputKISSTNCFrame.charAt(1) == CMD_DATA;
if (dataFrame){
String ax25Frame = decapsulateKISS(inputKISSTNCFrame);
TNC2Frame += ax25Frame;
}
return TNC2Frame;
}
/**
* Encode adress in TNC2 monitor format to ax.25 format

View File

@ -27,8 +27,5 @@
//END
String encode_kiss(const String& tnc2FormattedFrame);
String decode_kiss(const String &inputKISSTNCFrame, bool &dataFrame);
//PACKET MODE
String encode_kiss_pkt(const String& tnc2FormattedFrame);
String decode_kiss_pkt(const String &inputKISSTNCFrame, bool &dataFrame);
String encapsulateKISS(const String &ax25Frame, uint8_t TNCCmd);