Encode TNC2 monitor frame to KISS format

pull/2/head
Łukasz Nidecki 2 years ago
parent b22fa29fa5
commit 73e77ef8a3
  1. 0
      lib/KISS_TO_TNC2/KISS.h
  2. 100
      lib/KISS_TO_TNC2/KISS_TO_TNC2.cpp
  3. 9
      lib/KISS_TO_TNC2/KISS_TO_TNC2.h
  4. 21
      src/TTGO_T-Beam_LoRa_APRS.ino
  5. 4
      src/TTGO_T-Beam_LoRa_APRS_config.h

@ -0,0 +1,100 @@
#include "KISS_TO_TNC2.h"
bool validateTNC2Frame(const String &tnc2FormattedFrame);
String encode_address_kiss(String tnc2Address, bool isLast);
/*
* 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.
*/
String encode_kiss(const String& tnc2FormattedFrame) {
String ax25Frame = "";
if (validateTNC2Frame(tnc2FormattedFrame)){
String address = "";
for (int p=0;p<tnc2FormattedFrame.indexOf(':');p++){
char currentChar = tnc2FormattedFrame.charAt(p);
if (currentChar == ':' || currentChar == '>' || currentChar == ','){
if (currentChar == '>'){
// ax25 frame DST SRC
// tnc2 frame SRC DST
ax25Frame = encode_address_kiss(address, currentChar == ':') + ax25Frame;
} else {
ax25Frame += encode_address_kiss(address, currentChar == ':');
}
} else {
address += currentChar;
}
}
ax25Frame += (char)APRS_CONTROL_FIELD;
ax25Frame += (char)APRS_INFORMATION_FIELD;
ax25Frame += tnc2FormattedFrame.substring(tnc2FormattedFrame.indexOf(':')+1);
}
String kissFrame = "";
kissFrame += (char)FEND; // start of frame
kissFrame += (char)CMD_DATA; // TNC0, DATA
for (int i = 0; i < ax25Frame.length(); ++i) {
char currentChar = tnc2FormattedFrame.charAt(i);
if (currentChar == (char)FEND) {
kissFrame += FESC;
kissFrame += TFEND;
} else if (currentChar == (char)FESC){
kissFrame += FESC;
kissFrame += TFESC;
} else {
kissFrame += currentChar;
}
}
kissFrame += (char)FEND; // end of frame
return kissFrame;
}
/**
* Encode adress in TNC2 monitor format to ax.25/kiss format
* @param tnc2Address
* @param isLast
* @return
*/
String encode_address_kiss(String tnc2Address, bool isLast) {
if (tnc2Address.indexOf('-') == -1){
tnc2Address += "-0";
}
bool hasBeenDigipited = tnc2Address.indexOf('*') != -1;
int ssid = tnc2Address.substring(tnc2Address.indexOf('-')+1).toInt();
// TODO: SSID should not be > 16
String kissAddress = "";
for (int i = 0; i < 6; ++i) {
if (tnc2Address.length() > i){
kissAddress += (char)(tnc2Address.charAt(i) << 1);
} else {
kissAddress += ' ';
}
}
kissAddress += (char)((ssid << 1) | 0b01100000 | (isLast ? 1 : 0) | (hasBeenDigipited ? 0b10000000 : 0));
return kissAddress;
}
bool validateTNC2Frame(const String &tnc2FormattedFrame) { return (tnc2FormattedFrame.indexOf(':') != -1) && (tnc2FormattedFrame.indexOf('>') != -1); }

@ -0,0 +1,9 @@
#include <Arduino.h>
#include "KISS.h"
#define APRS_CONTROL_FIELD 0x03
#define APRS_INFORMATION_FIELD 0xf0
String encode_kiss(const String& tnc2FormattedFrame);
String decode_kiss(String kissFormattedFrame);

@ -21,7 +21,7 @@
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <axp20x.h>
#include "KISS.h"
#include <KISS_TO_TNC2.h>
// I2C LINES
#define I2C_SDA 21
@ -283,23 +283,6 @@ void writedisplaytext(String HeaderTxt, String Line1, String Line2, String Line3
display.display();
smartDelay(warten);
}
void encode_address(){
}
void decode_address(){
}
void encode_kiss(){
}
void decode_kiss(){
}
// + SETUP --------------------------------------------------------------+//
void setup(){
@ -405,7 +388,7 @@ void loop() {
Serial.println(InputString);
#endif
#ifdef KISS_PROTOCOLL
//encode_kiss(InputString);
Serial.println(encode_kiss(InputString));
#endif
writedisplaytext(" ((RX))","",InputString,"","","",SHOW_RX_TIME);
}

@ -5,8 +5,8 @@
// licensed under CC BY-NC-SA
// USER DATA - USE THESE LINES TO MODIFY YOUR PREFERENCES
//#define KISS_PROTOCOLL // If enabled send and receive data in SIMPLE KISS format
#define TEXT_PROTOCOLL // TEXT outpu data
#define KISS_PROTOCOLL // If enabled send and receive data in SIMPLE KISS format
//#define TEXT_PROTOCOLL // TEXT outpu data
#define CALLSIGN "SQ9MDD-11" // enter your callsign here - less then 6 letter callsigns please add "spaces" so total length is 6 (without SSID)
//#define LONGITUDE_PRESET "02055.59E" // please in APRS notation DDDMM.mmE or DDDMM.mmW
//#define LATIDUDE_PRESET "5215.02N" // please in APRS notation DDMM.mmN or DDMM.mmS

Loading…
Cancel
Save