mirror of https://github.com/SQ9MDD/ESP32IGate.git
461 lines
8.7 KiB
C++
461 lines
8.7 KiB
C++
#include "Arduino.h"
|
|
#include "AFSK.h"
|
|
#include "AX25.h"
|
|
// extern "C" {
|
|
// //#include "user_interface.h"
|
|
// }uint32_t freemem = system_get_free_heap_size();
|
|
Afsk modem;
|
|
AX25Ctx AX25;
|
|
extern void aprs_msg_callback(struct AX25Msg *msg);
|
|
|
|
#define countof(a) sizeof(a) / sizeof(a[0])
|
|
|
|
unsigned long custom_preamble = 350UL;
|
|
unsigned long custom_tail = 50UL;
|
|
|
|
AX25Call src;
|
|
AX25Call dst;
|
|
AX25Call path1;
|
|
AX25Call path2;
|
|
|
|
char CALL[7] = "NOCALL";
|
|
int CALL_SSID = 0;
|
|
char DST[7] = "APE32I";
|
|
int DST_SSID = 0;
|
|
char PATH1[7] = "WIDE1";
|
|
int PATH1_SSID = 1;
|
|
char PATH2[7] = "WIDE2";
|
|
int PATH2_SSID = 2;
|
|
|
|
AX25Call path[8];
|
|
|
|
// Location packet assembly fields
|
|
char latitude[9];
|
|
char longtitude[10];
|
|
char symbolTable = '/';
|
|
char symbol = 'n';
|
|
|
|
uint8_t power = 10;
|
|
uint8_t height = 10;
|
|
uint8_t gain = 10;
|
|
uint8_t directivity = 10;
|
|
/////////////////////////
|
|
|
|
// Message packet assembly fields
|
|
char message_recip[7];
|
|
int message_recip_ssid = -1;
|
|
|
|
int message_seq = 0;
|
|
char lastMessage[67];
|
|
size_t lastMessageLen;
|
|
bool message_autoAck = false;
|
|
/////////////////////////
|
|
|
|
void APRS_init()
|
|
{
|
|
AFSK_init(&modem);
|
|
ax25_init(&AX25, aprs_msg_callback);
|
|
}
|
|
|
|
void APRS_poll(void)
|
|
{
|
|
ax25_poll(&AX25);
|
|
}
|
|
|
|
void APRS_setCallsign(char *call, int ssid)
|
|
{
|
|
memset(CALL, 0, 7);
|
|
int i = 0;
|
|
while (i < 6 && call[i] != 0)
|
|
{
|
|
CALL[i] = call[i];
|
|
i++;
|
|
}
|
|
CALL_SSID = ssid;
|
|
}
|
|
|
|
void APRS_setDestination(char *call, int ssid)
|
|
{
|
|
memset(DST, 0, 7);
|
|
int i = 0;
|
|
while (i < 6 && call[i] != 0)
|
|
{
|
|
DST[i] = call[i];
|
|
i++;
|
|
}
|
|
DST_SSID = ssid;
|
|
}
|
|
|
|
void APRS_setPath1(char *call, int ssid)
|
|
{
|
|
memset(PATH1, 0, 7);
|
|
int i = 0;
|
|
while (i < 6 && call[i] != 0)
|
|
{
|
|
PATH1[i] = call[i];
|
|
i++;
|
|
}
|
|
PATH1_SSID = ssid;
|
|
}
|
|
|
|
void APRS_setPath2(char *call, int ssid)
|
|
{
|
|
memset(PATH2, 0, 7);
|
|
int i = 0;
|
|
while (i < 6 && call[i] != 0)
|
|
{
|
|
PATH2[i] = call[i];
|
|
i++;
|
|
}
|
|
PATH2_SSID = ssid;
|
|
}
|
|
|
|
void APRS_setMessageDestination(char *call, int ssid)
|
|
{
|
|
memset(message_recip, 0, 7);
|
|
int i = 0;
|
|
while (i < 6 && call[i] != 0)
|
|
{
|
|
message_recip[i] = call[i];
|
|
i++;
|
|
}
|
|
message_recip_ssid = ssid;
|
|
}
|
|
|
|
void APRS_setPreamble(unsigned long pre)
|
|
{
|
|
custom_preamble = pre;
|
|
}
|
|
|
|
void APRS_setTail(unsigned long tail)
|
|
{
|
|
custom_tail = tail;
|
|
}
|
|
|
|
void APRS_useAlternateSymbolTable(bool use)
|
|
{
|
|
if (use)
|
|
{
|
|
symbolTable = '\\';
|
|
}
|
|
else
|
|
{
|
|
symbolTable = '/';
|
|
}
|
|
}
|
|
|
|
void APRS_setSymbol(char sym)
|
|
{
|
|
symbol = sym;
|
|
}
|
|
|
|
void APRS_setLat(char *lat)
|
|
{
|
|
memset(latitude, 0, 9);
|
|
int i = 0;
|
|
while (i < 8 && lat[i] != 0)
|
|
{
|
|
latitude[i] = lat[i];
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void APRS_setLon(char *lon)
|
|
{
|
|
memset(longtitude, 0, 10);
|
|
int i = 0;
|
|
while (i < 9 && lon[i] != 0)
|
|
{
|
|
longtitude[i] = lon[i];
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void APRS_setPower(int s)
|
|
{
|
|
if (s >= 0 && s < 10)
|
|
{
|
|
power = s;
|
|
}
|
|
}
|
|
|
|
void APRS_setHeight(int s)
|
|
{
|
|
if (s >= 0 && s < 10)
|
|
{
|
|
height = s;
|
|
}
|
|
}
|
|
|
|
void APRS_setGain(int s)
|
|
{
|
|
if (s >= 0 && s < 10)
|
|
{
|
|
gain = s;
|
|
}
|
|
}
|
|
|
|
void APRS_setDirectivity(int s)
|
|
{
|
|
if (s >= 0 && s < 10)
|
|
{
|
|
directivity = s;
|
|
}
|
|
}
|
|
|
|
void APRS_printSettings()
|
|
{
|
|
Serial.println(F("LibAPRS Settings:"));
|
|
Serial.print(F("Callsign: "));
|
|
Serial.print(CALL);
|
|
Serial.print(F("-"));
|
|
Serial.println(CALL_SSID);
|
|
Serial.print(F("Destination: "));
|
|
Serial.print(DST);
|
|
Serial.print(F("-"));
|
|
Serial.println(DST_SSID);
|
|
Serial.print(F("Path1: "));
|
|
Serial.print(PATH1);
|
|
Serial.print(F("-"));
|
|
Serial.println(PATH1_SSID);
|
|
Serial.print(F("Path2: "));
|
|
Serial.print(PATH2);
|
|
Serial.print(F("-"));
|
|
Serial.println(PATH2_SSID);
|
|
Serial.print(F("Message dst: "));
|
|
if (message_recip[0] == 0)
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
else
|
|
{
|
|
Serial.print(message_recip);
|
|
Serial.print(F("-"));
|
|
Serial.println(message_recip_ssid);
|
|
}
|
|
Serial.print(F("TX Preamble: "));
|
|
Serial.println(custom_preamble);
|
|
Serial.print(F("TX Tail: "));
|
|
Serial.println(custom_tail);
|
|
Serial.print(F("Symbol table: "));
|
|
if (symbolTable == '/')
|
|
{
|
|
Serial.println(F("Normal"));
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("Alternate"));
|
|
}
|
|
Serial.print(F("Symbol: "));
|
|
Serial.println(symbol);
|
|
Serial.print(F("Power: "));
|
|
if (power < 10)
|
|
{
|
|
Serial.println(power);
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
Serial.print(F("Height: "));
|
|
if (height < 10)
|
|
{
|
|
Serial.println(height);
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
Serial.print(F("Gain: "));
|
|
if (gain < 10)
|
|
{
|
|
Serial.println(gain);
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
Serial.print(F("Directivity: "));
|
|
if (directivity < 10)
|
|
{
|
|
Serial.println(directivity);
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
Serial.print(F("Latitude: "));
|
|
if (latitude[0] != 0)
|
|
{
|
|
Serial.println(latitude);
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
Serial.print(F("Longtitude: "));
|
|
if (longtitude[0] != 0)
|
|
{
|
|
Serial.println(longtitude);
|
|
}
|
|
else
|
|
{
|
|
Serial.println(F("N/A"));
|
|
}
|
|
}
|
|
|
|
void APRS_sendPkt(void *_buffer, size_t length)
|
|
{
|
|
|
|
uint8_t *buffer = (uint8_t *)_buffer;
|
|
|
|
memcpy(dst.call, DST, 6);
|
|
dst.ssid = DST_SSID;
|
|
|
|
memcpy(src.call, CALL, 6);
|
|
src.ssid = CALL_SSID;
|
|
|
|
memcpy(path1.call, PATH1, 6);
|
|
path1.ssid = PATH1_SSID;
|
|
|
|
memcpy(path2.call, PATH2, 6);
|
|
path2.ssid = PATH2_SSID;
|
|
|
|
path[0] = dst;
|
|
path[1] = src;
|
|
path[2] = path1;
|
|
path[3] = path2;
|
|
|
|
ax25_sendVia(&AX25, path, countof(path), buffer, length);
|
|
}
|
|
|
|
void APRS_sendTNC2Pkt(String raw)
|
|
{
|
|
ax25frame frame;
|
|
// Serial.println(raw);
|
|
ax25_encode(frame, (char *)raw.c_str(), raw.length());
|
|
ax25sendFrame(&AX25, &frame);
|
|
}
|
|
|
|
// Dynamic RAM usage of this function is 30 bytes
|
|
void APRS_sendLoc(void *_buffer, size_t length)
|
|
{
|
|
size_t payloadLength = 20 + length;
|
|
bool usePHG = false;
|
|
if (power < 10 && height < 10 && gain < 10 && directivity < 9)
|
|
{
|
|
usePHG = true;
|
|
payloadLength += 7;
|
|
}
|
|
uint8_t *packet = (uint8_t *)malloc(payloadLength);
|
|
uint8_t *ptr = packet;
|
|
packet[0] = '=';
|
|
packet[9] = symbolTable;
|
|
packet[19] = symbol;
|
|
ptr++;
|
|
memcpy(ptr, latitude, 8);
|
|
ptr += 9;
|
|
memcpy(ptr, longtitude, 9);
|
|
ptr += 10;
|
|
if (usePHG)
|
|
{
|
|
packet[20] = 'P';
|
|
packet[21] = 'H';
|
|
packet[22] = 'G';
|
|
packet[23] = power + 48;
|
|
packet[24] = height + 48;
|
|
packet[25] = gain + 48;
|
|
packet[26] = directivity + 48;
|
|
ptr += 7;
|
|
}
|
|
if (length > 0)
|
|
{
|
|
uint8_t *buffer = (uint8_t *)_buffer;
|
|
memcpy(ptr, buffer, length);
|
|
}
|
|
|
|
APRS_sendPkt(packet, payloadLength);
|
|
free(packet);
|
|
}
|
|
|
|
// Dynamic RAM usage of this function is 18 bytes
|
|
void APRS_sendMsg(void *_buffer, size_t length)
|
|
{
|
|
if (length > 67)
|
|
length = 67;
|
|
size_t payloadLength = 11 + length + 4;
|
|
|
|
uint8_t *packet = (uint8_t *)malloc(payloadLength);
|
|
uint8_t *ptr = packet;
|
|
packet[0] = ':';
|
|
int callSize = 6;
|
|
int count = 0;
|
|
while (callSize--)
|
|
{
|
|
if (message_recip[count] != 0)
|
|
{
|
|
packet[1 + count] = message_recip[count];
|
|
count++;
|
|
}
|
|
}
|
|
if (message_recip_ssid != -1)
|
|
{
|
|
packet[1 + count] = '-';
|
|
count++;
|
|
if (message_recip_ssid < 10)
|
|
{
|
|
packet[1 + count] = message_recip_ssid + 48;
|
|
count++;
|
|
}
|
|
else
|
|
{
|
|
packet[1 + count] = 49;
|
|
count++;
|
|
packet[1 + count] = message_recip_ssid - 10 + 48;
|
|
count++;
|
|
}
|
|
}
|
|
while (count < 9)
|
|
{
|
|
packet[1 + count] = ' ';
|
|
count++;
|
|
}
|
|
packet[1 + count] = ':';
|
|
ptr += 11;
|
|
if (length > 0)
|
|
{
|
|
uint8_t *buffer = (uint8_t *)_buffer;
|
|
memcpy(ptr, buffer, length);
|
|
memcpy(lastMessage, buffer, length);
|
|
lastMessageLen = length;
|
|
}
|
|
|
|
message_seq++;
|
|
if (message_seq > 999)
|
|
message_seq = 0;
|
|
|
|
packet[11 + length] = '{';
|
|
int n = message_seq % 10;
|
|
int d = ((message_seq % 100) - n) / 10;
|
|
int h = (message_seq - d - n) / 100;
|
|
|
|
packet[12 + length] = h + 48;
|
|
packet[13 + length] = d + 48;
|
|
packet[14 + length] = n + 48;
|
|
|
|
APRS_sendPkt(packet, payloadLength);
|
|
free(packet);
|
|
}
|
|
|
|
void APRS_msgRetry()
|
|
{
|
|
message_seq--;
|
|
APRS_sendMsg(lastMessage, lastMessageLen);
|
|
}
|
|
|
|
int freeMemory()
|
|
{
|
|
int free_memory = ESP.getFreeHeap();
|
|
return free_memory;
|
|
}
|