LibAPRS/LibAPRS.cpp

309 wiersze
7.5 KiB
C++

#include "Arduino.h"
#include "AFSK.h"
#include "AX25.h"
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] = "APZMDM";
int DST_SSID = 0;
char PATH1[7] = "WIDE1";
int PATH1_SSID = 1;
char PATH2[7] = "WIDE2";
int PATH2_SSID = 2;
AX25Call path[4];
// 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(void) {
AFSK_init(&modem);
ax25_init(&AX25, aprs_msg_callback);
}
void APRS_poll(void) {
ax25_poll(&AX25);
}
void APRS_setCallsign(char *call, int ssid) {
Serial.println("Setting to: ");
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("LibAPRS Settings:");
Serial.print("Callsign: "); Serial.print(CALL); Serial.print("-"); Serial.println(CALL_SSID);
Serial.print("Destination: "); Serial.print(DST); Serial.print("-"); Serial.println(DST_SSID);
Serial.print("Path1: "); Serial.print(PATH1); Serial.print("-"); Serial.println(PATH1_SSID);
Serial.print("Path2: "); Serial.print(PATH2); Serial.print("-"); Serial.println(PATH2_SSID);
Serial.print("Message dst: "); if (message_recip[0] == 0) { Serial.println("N/A"); } else { Serial.print(message_recip); Serial.print("-"); Serial.println(message_recip_ssid); }
Serial.print("TX Preamble: "); Serial.println(custom_preamble);
Serial.print("TX Tail: "); Serial.println(custom_tail);
Serial.print("Symbol table: "); if (symbolTable = '/') { Serial.println("Normal"); } else { Serial.println("Alternate"); }
Serial.print("Symbol: "); Serial.println(symbol);
Serial.print("Power: "); if (power < 10) { Serial.println(power); } else { Serial.println("N/A"); }
Serial.print("Height: "); if (height < 10) { Serial.println(height); } else { Serial.println("N/A"); }
Serial.print("Gain: "); if (gain < 10) { Serial.println(gain); } else { Serial.println("N/A"); }
Serial.print("Directivity: "); if (directivity < 10) { Serial.println(directivity); } else { Serial.println("N/A"); }
Serial.print("Latitude: "); if (latitude[0] != 0) { Serial.println(latitude); } else { Serial.println("N/A"); }
Serial.print("Longtitude: "); if (longtitude[0] != 0) { Serial.println(longtitude); } else { Serial.println("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_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);
}
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);
}