Skip to content

Commit

Permalink
use common encoder and decoder procedures both for Classic and LoRa A…
Browse files Browse the repository at this point in the history
…PRS protocols
  • Loading branch information
lyusupov committed Aug 24, 2023
1 parent 5c405dc commit ce426a0
Show file tree
Hide file tree
Showing 11 changed files with 34 additions and 158 deletions.
9 changes: 4 additions & 5 deletions software/firmware/source/SoftRF/src/driver/RF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,8 +934,8 @@ static void sx12xx_setup()
#if defined(ENABLE_PROL)
case RF_PROTOCOL_APRS:
LMIC.protocol = &prol_proto_desc;
protocol_encode = &prol_encode;
protocol_decode = &prol_decode;
protocol_encode = &aprs_encode;
protocol_decode = &aprs_decode;
break;
#endif /* ENABLE_PROL */
case RF_PROTOCOL_LEGACY:
Expand Down Expand Up @@ -2334,7 +2334,6 @@ static void ognrf_shutdown()
#endif /* USE_OGN_RF_DRIVER */

AX25Msg Incoming_APRS_Packet;
char Outgoing_APRS_Data[160];

#if defined(USE_SA8X8)
SA818 sa868(&SA8X8_Serial);
Expand Down Expand Up @@ -2466,7 +2465,7 @@ static void sa8x8_setup()
controller.setVolume(1);

protocol_encode = &aprs_encode;
protocol_decode = &aprs_decode;
protocol_decode = &ax25_decode;

PacketBuffer.clean();

Expand Down Expand Up @@ -2522,7 +2521,7 @@ static void sa8x8_transmit()
uint8_t powerPin = SOC_GPIO_PIN_TWR2_RADIO_HL;
AFSK_TimerEnable(false);

APRS_sendTNC2Pkt(String(Outgoing_APRS_Data));
APRS_sendTNC2Pkt(String((char *) TxBuffer));

do {
delay(5);
Expand Down
4 changes: 2 additions & 2 deletions software/firmware/source/SoftRF/src/driver/RF.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
#define MAX_PKT_SIZE maxof5(LEGACY_PAYLOAD_SIZE, OGNTP_PAYLOAD_SIZE, \
P3I_PAYLOAD_SIZE, FANET_PAYLOAD_SIZE, \
UAT978_PAYLOAD_SIZE)
#if defined(ENABLE_PROL)
#if defined(ENABLE_PROL) || defined(USE_SA8X8)
#undef MAX_PKT_SIZE
#define MAX_PKT_SIZE maxof2(maxof5(LEGACY_PAYLOAD_SIZE, OGNTP_PAYLOAD_SIZE, \
P3I_PAYLOAD_SIZE, FANET_PAYLOAD_SIZE, \
UAT978_PAYLOAD_SIZE), PROL_PAYLOAD_SIZE)
UAT978_PAYLOAD_SIZE), APRS_PAYLOAD_SIZE)
#endif /* ENABLE_PROL */

#define RXADDR {0x31, 0xfa , 0xb6} // Address of this device (4 bytes)
Expand Down
149 changes: 17 additions & 132 deletions software/firmware/source/SoftRF/src/protocol/radio/APRS.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
*
* Protocol_APRS.cpp
* Encoder for Automatic Packet Reporting System radio protocol
*
* Encoder and decoder for Automatic Packet Reporting System radio protocol
* Copyright (C) 2023 Linar Yusupov
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -77,7 +77,6 @@ static const char *AprsIcon[16] = // Icons for various FLARM acftType's
};

extern AX25Msg Incoming_APRS_Packet;
extern char Outgoing_APRS_Data[160];

struct pbuf_t aprs;
ParseAPRS aprsParse;
Expand Down Expand Up @@ -124,8 +123,7 @@ int packet2Raw(String &tnc2, AX25Msg &Packet) {

bool aprs_decode(void *pkt, ufo_t *this_aircraft, ufo_t *fop) {

String tnc2;
packet2Raw(tnc2, Incoming_APRS_Packet);
String tnc2((char *) pkt);

// Serial.println("APRS RX: " + tnc2);

Expand Down Expand Up @@ -189,6 +187,13 @@ bool aprs_decode(void *pkt, ufo_t *this_aircraft, ufo_t *fop) {
return false;
}

bool ax25_decode(void *pkt, ufo_t *this_aircraft, ufo_t *fop) {
String tnc2;
packet2Raw(tnc2, Incoming_APRS_Packet);

return aprs_decode((void *) tnc2.c_str(), this_aircraft, fop);
}

static void nmea_lat(float lat, char *buf)
{
int lat_int = (int) lat;
Expand All @@ -207,6 +212,7 @@ static void nmea_lon(float lon, char *buf)

size_t aprs_encode(void *pkt, ufo_t *this_aircraft) {

char buf[APRS_PAYLOAD_SIZE];
uint32_t id = this_aircraft->addr & 0x00FFFFFF;

#if !defined(SOFTRF_ADDRESS)
Expand All @@ -233,15 +239,16 @@ size_t aprs_encode(void *pkt, ufo_t *this_aircraft) {
int lon_int = (int) lon;
float lon_dec = lon - lon_int;

snprintf(Outgoing_APRS_Data, sizeof(Outgoing_APRS_Data),
snprintf(buf, sizeof(buf),
// "<\xff\x01"
"%06X>%s:"
"/"
"%02d%02d%02dh"
"%02d%05.2f%c"
"/"
"%03d%05.2f%c"
"'"
"%03d/%03d/A=%06d !W00! id%08X +000fpm +0.0rot 7.8dB -1.6kHz gps8x3",
"%03d/%03d/A=%06d !W00! id%08X +000fpm +0.0rot" /* " 7.8dB -1.6kHz gps8x3" */,
id, "OGFLR",
gnss.time.hour(), gnss.time.minute(), gnss.time.second(),
abs(lat_int), fabsf(lat_dec * 60), lat < 0 ? 'S' : 'N',
Expand All @@ -251,12 +258,10 @@ size_t aprs_encode(void *pkt, ufo_t *this_aircraft) {
(altitude_i < 0) ? 0 : altitude_i, /* feet */
id | (XX << 24));

strcpy((char *) pkt, "NOT IN USE");

return aprs_proto_desc.payload_size;
memcpy((void *) pkt, buf, strlen(buf));
return strlen(buf);
}

#if defined(ENABLE_PROL)
/*
* APRS-over-LoRa
*/
Expand All @@ -270,7 +275,7 @@ const rf_proto_desc_t prol_proto_desc = {
.syncword_size = 1,
.net_id = 0x0000, /* not in use */
.payload_type = RF_PAYLOAD_DIRECT,
.payload_size = PROL_PAYLOAD_SIZE,
.payload_size = APRS_PAYLOAD_SIZE,
.payload_offset = PROL_PAYLOAD_OFFSET,
.crc_type = RF_CHECKSUM_TYPE_NONE, /* LoRa packet has built-in CRC */
.crc_size = 0 /* INVALID FOR LORA */,
Expand All @@ -288,123 +293,3 @@ const rf_proto_desc_t prol_proto_desc = {
.slot0 = {0, 0},
.slot1 = {0, 0}
};

bool prol_decode(void *pkt, ufo_t *this_aircraft, ufo_t *fop) {

String tnc2((char *) pkt);

// Serial.println("APRS RX: " + tnc2);

int start_val = tnc2.indexOf(">", 0);
if (start_val > 3)
{
String src_call = tnc2.substring(0, start_val);
memset(&aprs, 0, sizeof(pbuf_t));
aprs.buf_len = 300;
aprs.packet_len = tnc2.length();
tnc2.toCharArray(&aprs.data[0], aprs.packet_len);
int start_info = tnc2.indexOf(":", 0);
int end_ssid = tnc2.indexOf(",", 0);
int start_dst = tnc2.indexOf(">", 2);
int start_dstssid = tnc2.indexOf("-", start_dst);
if ((start_dstssid > start_dst) && (start_dstssid < start_dst + 10))
{
aprs.dstcall_end_or_ssid = &aprs.data[start_dstssid];
}
else
{
aprs.dstcall_end_or_ssid = &aprs.data[end_ssid];
}
aprs.info_start = &aprs.data[start_info + 1];
aprs.dstname = &aprs.data[start_dst + 1];
aprs.dstname_len = end_ssid - start_dst;
aprs.dstcall_end = &aprs.data[end_ssid];
aprs.srccall_end = &aprs.data[start_dst];

if (aprsParse.parse_aprs(&aprs))
{
#if 0 // ndef RASPBERRY_PI
Serial.print("lat: "); Serial.println(aprs.lat);
Serial.print("lon: "); Serial.println(aprs.lng);
Serial.print("alt: "); Serial.println(aprs.altitude);
Serial.print("crs: "); Serial.println(aprs.course);
Serial.print("spd: "); Serial.println(aprs.speed);
Serial.print("id: "); Serial.println(aprs.ogn_id, HEX);
#endif

fop->protocol = RF_PROTOCOL_APRS;

fop->addr = aprs.ogn_id & 0x00FFFFFF;
fop->latitude = aprs.lat;
fop->longitude = aprs.lng;
fop->altitude = (float) aprs.altitude; /* metres */
fop->course = (aprs.course == 360) ? 0 : (float) aprs.course;
fop->speed = (float) aprs.speed / _GPS_KMPH_PER_KNOT; /* knots */
fop->timestamp = (uint32_t) this_aircraft->timestamp;

uint8_t XX = (aprs.ogn_id >> 24) & 0xFF;
fop->addr_type = XX & 0x3;
fop->aircraft_type = (XX >> 2) & 0xF;
fop->no_track = (XX >> 6) & 0x1;
fop->stealth = (XX >> 7) & 0x1;

if (fop->addr) return true;
}
}

return false;
}

size_t prol_encode(void *pkt, ufo_t *this_aircraft) {

char buf[PROL_PAYLOAD_SIZE];
uint32_t id = this_aircraft->addr & 0x00FFFFFF;

#if !defined(SOFTRF_ADDRESS)
uint8_t addr_type = ADDR_TYPE_ANONYMOUS;
#else
uint8_t addr_type = id == SOFTRF_ADDRESS ? ADDR_TYPE_ICAO : ADDR_TYPE_ANONYMOUS;
#endif

uint8_t acft_type = this_aircraft->aircraft_type > AIRCRAFT_TYPE_STATIC ?
AIRCRAFT_TYPE_UNKNOWN : this_aircraft->aircraft_type;

int course_i = (int) this_aircraft->course;
int altitude_i = (int) (this_aircraft->altitude * _GPS_FEET_PER_METER);

uint32_t XX = (this_aircraft->stealth << 7UL) |
(this_aircraft->no_track << 6UL) |
(acft_type << 2UL) |
(addr_type );

float lat = this_aircraft->latitude;
float lon = this_aircraft->longitude;
int lat_int = (int) lat;
float lat_dec = lat - lat_int;
int lon_int = (int) lon;
float lon_dec = lon - lon_int;

snprintf(buf, sizeof(buf),
// "<\xff\x01"
"%06X>%s:"
"/"
"%02d%02d%02dh"
"%02d%05.2f%c"
"/"
"%03d%05.2f%c"
"'"
"%03d/%03d/A=%06d !W00! id%08X +000fpm +0.0rot" /* " 7.8dB -1.6kHz gps8x3" */,
id, "OGFLR",
gnss.time.hour(), gnss.time.minute(), gnss.time.second(),
abs(lat_int), fabsf(lat_dec * 60), lat < 0 ? 'S' : 'N',
abs(lon_int), fabsf(lon_dec * 60), lon < 0 ? 'W' : 'E',
(course_i == 0) ? 360 : course_i,
(int) this_aircraft->speed, /* knots */
(altitude_i < 0) ? 0 : altitude_i, /* feet */
id | (XX << 24));

memcpy((void *) pkt, buf, strlen(buf));
return strlen(buf);
}

#endif /* ENABLE_PROL */
17 changes: 6 additions & 11 deletions software/firmware/source/SoftRF/src/protocol/radio/APRS.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
*
* Protocol_APRS.h
* Encoder for Automatic Packet Reporting System radio protocol
*
* Encoder and decoder for Automatic Packet Reporting System radio protocol
* Copyright (C) 2023 Linar Yusupov
*
* This program is free software: you can redistribute it and/or modify
Expand All @@ -28,13 +28,13 @@

#define APRS_SYNCWORD { 0x00 } /* TBD */
#define APRS_SYNCWORD_SIZE 1
#define APRS_PAYLOAD_SIZE AX25_MIN_FRAME_LEN
#define APRS_PAYLOAD_SIZE 120 /* TBD */
#define APRS_CRC_TYPE RF_CHECKSUM_TYPE_CCITT_FFFF
#define APRS_CRC_SIZE 2

#define APRS_AIR_TIME 3000 /* 3 s */

#define APRS_TX_INTERVAL_MIN 60000 /* in ms, no SB support at this time */
#define APRS_TX_INTERVAL_MIN 60000 /* in ms, no SB nor LBT support at this time */
#define APRS_TX_INTERVAL_MAX 65500 /* TBD: 80000 */

typedef struct {
Expand All @@ -45,25 +45,20 @@ typedef struct {

extern const rf_proto_desc_t aprs_proto_desc;

bool ax25_decode(void *, ufo_t *, ufo_t *);
bool aprs_decode(void *, ufo_t *, ufo_t *);
size_t aprs_encode(void *, ufo_t *);

#if defined(ENABLE_PROL)
/*
* APRS-over-LoRa
*/
#define PROL_PAYLOAD_SIZE 120 /* TBD */
#define PROL_PAYLOAD_OFFSET 3

#define PROL_AIR_TIME 4600 /* 4.6 s */

#define PROL_TX_INTERVAL_MIN 60000 /* in ms, no SB support at this time */
#define PROL_TX_INTERVAL_MIN 60000 /* in ms, no SB nor LBT support at this time */
#define PROL_TX_INTERVAL_MAX 65500 /* TBD: 80000 */

extern const rf_proto_desc_t prol_proto_desc;

bool prol_decode(void *, ufo_t *, ufo_t *);
size_t prol_encode(void *, ufo_t *);

#endif /* ENABLE_PROL */
#endif /* PROTOCOL_APRS_H */
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Protocol_ES1090.h
*
* Decoder for Extended Squitter 1090 MHz ADS-B radio protocol
* Copyright (C) 2021-2023 Linar Yusupov
*
Expand Down
1 change: 0 additions & 1 deletion software/firmware/source/SoftRF/src/protocol/radio/FANET.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
*
* Protocol_FANET.h
*
* Encoder and decoder for open FANET radio protocol
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Protocol_Legacy.h
*
* Copyright (C) 2014-2015 Stanislaw Pusep
* Copyright (C) 2016-2023 Linar Yusupov
*
Expand Down
2 changes: 1 addition & 1 deletion software/firmware/source/SoftRF/src/protocol/radio/OGNTP.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Protocol_OGNTP.h
*
* Encoder and decoder for Open Glider Network tracker radio protocol
* Copyright (C) 2017-2023 Linar Yusupov
*
Expand Down
1 change: 1 addition & 0 deletions software/firmware/source/SoftRF/src/protocol/radio/P3I.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Protocol_P3I.h
*
* Copyright (C) 2017-2023 Linar Yusupov
*
* This program is free software: you can redistribute it and/or modify
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Protocol_UAT978.h
*
* Decoder for UAT 978 MHz ADS-B radio protocol
* Copyright (C) 2019-2023 Linar Yusupov
*
Expand Down
4 changes: 0 additions & 4 deletions software/firmware/source/SoftRF/src/ui/Web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,7 @@ void handleSettings() {
(settings->rf_protocol == RF_PROTOCOL_FANET ? "selected" : ""),
RF_PROTOCOL_FANET, fanet_proto_desc.name,
(settings->rf_protocol == RF_PROTOCOL_APRS ? "selected" : ""),
#if defined(ENABLE_PROL)
RF_PROTOCOL_APRS, prol_proto_desc.name
#else
RF_PROTOCOL_APRS, "PRoL"
#endif /* ENABLE_PROL */
);
} else {
snprintf_P ( offset, size,
Expand Down

0 comments on commit ce426a0

Please sign in to comment.