#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); }