LoRa_APRS_Tracker111/lib/APRSPacketLib/APRSPacketLib.cpp

263 lines
11 KiB
C++

#include "APRSPacketLib.h"
namespace APRSPacketLib {
String generateBasePacket(String callsign, String tocall, String path) {
String packet = callsign + ">" + tocall;
if (path != "") {
packet += "," + path;
}
return packet;
}
String generateStatusPacket(String callsign, String tocall, String path, String status) {
return generateBasePacket(callsign,tocall,path) + ":>" + status;
}
String generateMessagePacket(String callsign, String tocall, String path, String addressee, String message) {
for(int i = addressee.length(); i < 9; i++) {
addressee += ' ';
}
return generateBasePacket(callsign,tocall,path) + "::" + addressee + ":" + message;
}
String generateDigiRepeatedPacket(APRSPacket packet, String callsign) {
if (packet.path.indexOf("WIDE1-")>=0) {
String hop = packet.path.substring(packet.path.indexOf("WIDE1-")+6, packet.path.indexOf("WIDE1-")+7);
if (hop.toInt()>=1 && hop.toInt()<=7) {
if (hop.toInt()==1) {
packet.path.replace("WIDE1-1", callsign + "*");
} else {
packet.path.replace("WIDE1-" + hop , callsign + "*,WIDE1-" + String(hop.toInt()-1));
}
String repeatedPacket = packet.sender + ">" + packet.tocall + "," + packet.path;
switch (packet.type) {
case 0: // gps
repeatedPacket += ":!";
break;
case 1: // message
for(int i = packet.addressee.length(); i < 9; i++) {
packet.addressee += ' ';
}
repeatedPacket += "::" + packet.addressee + ":";
break;
case 2: // status
repeatedPacket += ":>";
break;
case 3: // telemetry
repeatedPacket += ":T#";
break;
}
return repeatedPacket + packet.message;
} else {
return "X";
}
} else {
return "X";
}
}
char *ax25_base91enc(char *s, uint8_t n, uint32_t v) {
for(s += n, *s = '\0'; n; n--) {
*(--s) = v % 91 + 33;
v /= 91;
}
return(s);
}
String encondeGPS(float latitude, float longitude, float course, float speed, String symbol, bool sendAltitude, int altitude, bool sendStandingUpdate, String packetType) {
String encodedData;
uint32_t aprs_lat, aprs_lon;
aprs_lat = 900000000 - latitude * 10000000;
aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615;
aprs_lon = 900000000 + longitude * 10000000 / 2;
aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615;
String Ns, Ew, helper;
if(latitude < 0) { Ns = "S"; } else { Ns = "N"; }
if(latitude < 0) { latitude= -latitude; }
if(longitude < 0) { Ew = "W"; } else { Ew = "E"; }
if(longitude < 0) { longitude= -longitude; }
char helper_base91[] = {"0000\0"};
int i;
ax25_base91enc(helper_base91, 4, aprs_lat);
for (i=0; i<4; i++) {
encodedData += helper_base91[i];
}
ax25_base91enc(helper_base91, 4, aprs_lon);
for (i=0; i<4; i++) {
encodedData += helper_base91[i];
}
if (packetType=="Wx") {
encodedData += "_";
} else {
encodedData += symbol;
}
if (sendAltitude) { // Send Altitude or... (APRS calculates Speed also)
int Alt1, Alt2;
if(altitude>0) {
double ALT=log(altitude)/log(1.002);
Alt1= int(ALT/91);
Alt2=(int)ALT%91;
} else {
Alt1=0;
Alt2=0;
}
if (sendStandingUpdate) {
encodedData += " ";
} else {
encodedData +=char(Alt1+33);
}
encodedData +=char(Alt2+33);
encodedData +=char(0x30+33);
} else { // ... just send Course and Speed
ax25_base91enc(helper_base91, 1, (uint32_t) course/4 );
if (sendStandingUpdate) {
encodedData += " ";
} else {
encodedData += helper_base91[0];
}
ax25_base91enc(helper_base91, 1, (uint32_t) (log1p(speed)/0.07696));
encodedData += helper_base91[0];
encodedData += "\x47";
}
return encodedData;
}
String generateGPSBeaconPacket(String callsign, String tocall, String path, String overlay, String gps) {
return generateBasePacket(callsign,tocall,path) + ":!" + overlay + gps;
}
float decodeEncodedLatitude(String encodedLatitude) {
int Y1 = int(encodedLatitude[0]);
int Y2 = int(encodedLatitude[1]);
int Y3 = int(encodedLatitude[2]);
int Y4 = int(encodedLatitude[3]);
return (90.0 - ((((Y1-33) * pow(91,3)) + ((Y2-33) * pow(91,2)) + ((Y3-33) * 91) + Y4-33) / 380926.0));
}
float decodeEncodedLongitude(String encodedLongitude) {
int X1 = int(encodedLongitude[0]);
int X2 = int(encodedLongitude[1]);
int X3 = int(encodedLongitude[2]);
int X4 = int(encodedLongitude[3]);
return (-180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0));
}
float decodeLatitude(String Latitude) {
String firstLatPart = Latitude.substring(0,2);
String secondLatPart = Latitude.substring(2,4);
String thirdLatPart = Latitude.substring(Latitude.indexOf(".")+1,Latitude.indexOf(".")+3);
float convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
String LatSign = String(Latitude[7]);
if (LatSign == "S") {
return -convertedLatitude;;
} else {
return convertedLatitude;
}
}
float decodeLongitude(String Longitude) {
String firstLngPart = Longitude.substring(0,3);
String secondLngPart = Longitude.substring(3,5);
String thirdLngPart = Longitude.substring(Longitude.indexOf(".")+1,Longitude.indexOf(".")+3);
float convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
String LngSign = String(Longitude[8]);
if (LngSign == "W") {
return -convertedLongitude;
} else {
return convertedLongitude;
}
}
int decodeSpeed(String speed) {
return speed.toInt() * 1.852;
}
int decodeAltitude(String altitude) {
return altitude.toInt() * 0.3048;
}
APRSPacket processReceivedPacket(String receivedPacket) {
/* Packet type:
gps = 0
message = 1
status = 2
telemetry = 3 */
APRSPacket aprsPacket;
aprsPacket.sender = receivedPacket.substring(0,receivedPacket.indexOf(">"));
String temp00 = receivedPacket.substring(receivedPacket.indexOf(">")+1,receivedPacket.indexOf(":"));
if (temp00.indexOf(",") > 2) {
aprsPacket.tocall = temp00.substring(0,temp00.indexOf(","));
aprsPacket.path = temp00.substring(temp00.indexOf(",")+1,temp00.indexOf(":"));
} else {
aprsPacket.tocall = temp00;
aprsPacket.path = "";
}
if (receivedPacket.indexOf(":!") > 10 || receivedPacket.indexOf(":=") > 10 ) {
aprsPacket.type = 0;
aprsPacket.addressee = "";
String gpsChar = "";
if (receivedPacket.indexOf(":!") > 10) {
gpsChar = ":!";
} else {
gpsChar = ":=";
}
int encodedBytePosition = receivedPacket.indexOf(gpsChar) + 14;
aprsPacket.message = receivedPacket.substring(receivedPacket.indexOf(gpsChar)+2);
if (String(receivedPacket[encodedBytePosition]) == "G" || String(receivedPacket[encodedBytePosition]) == "Q" || String(receivedPacket[encodedBytePosition]) == "[" || String(receivedPacket[encodedBytePosition]) == "H") {
aprsPacket.latitude = decodeEncodedLatitude(receivedPacket.substring(receivedPacket.indexOf(gpsChar)+3, receivedPacket.indexOf(gpsChar)+7));
aprsPacket.longitude = decodeEncodedLongitude(receivedPacket.substring(receivedPacket.indexOf(gpsChar)+7, receivedPacket.indexOf(gpsChar)+11));
// revisar si es codificado con Speed+Course o Altitude+Course+Speed
// tambien conseguir Symbol
/*aprsPacket.symbol
aprsPacket.course
aprsPacket.speed
aprsPacket.altitude*/
Serial.println(aprsPacket.latitude);
Serial.println(aprsPacket.longitude);
} else {
aprsPacket.latitude = decodeLatitude(receivedPacket.substring(receivedPacket.indexOf(gpsChar)+2,receivedPacket.indexOf(gpsChar)+10));
aprsPacket.longitude = decodeLongitude(receivedPacket.substring(receivedPacket.indexOf(gpsChar)+11,receivedPacket.indexOf(gpsChar)+20));
aprsPacket.symbol = receivedPacket.substring(receivedPacket.indexOf(gpsChar)+20,receivedPacket.indexOf(gpsChar)+21);
if (receivedPacket.substring(receivedPacket.indexOf(gpsChar)+24,receivedPacket.indexOf(gpsChar)+25) == "/" && receivedPacket.substring(receivedPacket.indexOf(gpsChar)+28,receivedPacket.indexOf(gpsChar)+31) == "/A=") {
aprsPacket.course = receivedPacket.substring(receivedPacket.indexOf(gpsChar)+21,receivedPacket.indexOf(gpsChar)+24).toInt();
aprsPacket.speed = decodeSpeed(receivedPacket.substring(receivedPacket.indexOf(gpsChar)+25,receivedPacket.indexOf(gpsChar)+28));
aprsPacket.altitude = decodeAltitude(receivedPacket.substring(receivedPacket.indexOf(gpsChar)+31,receivedPacket.indexOf(gpsChar)+39));
} else {
aprsPacket.course = 0;
aprsPacket.speed = 0;
aprsPacket.altitude = 0;
}
}
} else if (receivedPacket.indexOf("::") > 10) {
aprsPacket.type = 1;
String temp1 = receivedPacket.substring(receivedPacket.indexOf("::")+2);
String temp2 = temp1.substring(0,temp1.indexOf(":"));
temp2.trim();
aprsPacket.addressee = temp2;
aprsPacket.message = temp1.substring(temp1.indexOf(":")+1);
aprsPacket.latitude = 0;
aprsPacket.longitude = 0;
} else if (receivedPacket.indexOf(":>") > 10) {
aprsPacket.type = 2;
aprsPacket.addressee = "";
aprsPacket.message = receivedPacket.substring(receivedPacket.indexOf(":>")+2);
aprsPacket.latitude = 0;
aprsPacket.longitude = 0;
} else if (receivedPacket.indexOf(":T#") >= 10 && receivedPacket.indexOf(":=/") == -1) {
aprsPacket.type = 3;
aprsPacket.addressee = "";
aprsPacket.message = receivedPacket.substring(receivedPacket.indexOf(":T#")+3);
aprsPacket.latitude = 0;
aprsPacket.longitude = 0;
}
return aprsPacket;
}
}