Decoding APRS frames finished, started with transmitting frames.

Committer: marcel <marcel@hampi.pe1rxf>
master
marcel 3 years ago
parent a074eb1ee9
commit 0445ec5ab9
  1. BIN
      build/src/CMakeFiles/main.dir/main.cpp.obj
  2. BIN
      build/src/main.bin
  3. 42550
      build/src/main.dis
  4. BIN
      build/src/main.elf
  5. 1550
      build/src/main.elf.map
  6. 6781
      build/src/main.hex
  7. BIN
      build/src/main.uf2
  8. 12
      src/Config.h
  9. 246
      src/main.cpp

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -28,7 +28,7 @@
int loraPreamble = 8;
int loraCodingRate = 5;
int loraTxPower = 17;
int LoRaPaSelect = 1;
int LoRaPaSelect = 0;
uint32_t loraBandwidth = 125E3;
uint32_t loraFrequency = 433775000;
@ -57,4 +57,14 @@
const uint8_t SIG_SYNCED = 0x02;
const uint8_t RX_ONGOING = 0x04;
struct aprssettings {
uint8_t MyCall[10] = { 'P','E','1','R','X','F','-','5', 0} ;
uint8_t ServerCall[10] = { 'P','E','1','R','X','F','-','3', 0} ;
uint8_t Destination[10] = { 'A','P','Z','M','D','M', 0} ;
uint8_t Path1[10] = { 0,'I','D','E','1','-', '1', 0} ;
uint8_t Path2[10] = { 0,'I','D','E','2','-', '2', 0} ;
uint8_t FirmwareVersion[20] = { 'V','1',',','C','o','n','t','r', 'o','l','l','e','r',' ','0','1', 0} ;
} AprsSettings;
#endif

@ -7,12 +7,20 @@
#include "KISS.h"
bool startRadio();
bool LoadSettings();
void getPacketData(int packetLength);
int compare_strings(uint8_t a[], uint8_t b[]);
bool is_message_for_me (uint8_t data[], uint8_t mycall[]);
void encode_kiss ();
uint16_t decode_packet ();
void ComposeAprsFrame(uint8_t payload[]);
void transmit();
int main() {
uint16_t ServerCommand = 0;
/* Among others, this initializes the USB-serial port at 115200bps 8N1 */
stdio_init_all();
@ -22,6 +30,8 @@ int main() {
sleep_ms(5000);
LoadSettings();
startRadio();
while (1) {
@ -40,16 +50,43 @@ int main() {
}
rxBuffer[packetSize-3] = 0;
printf("%s\n", rxBuffer);
encode_kiss();
ServerCommand = decode_packet();
} else {
printf("ERROR: No or corrupted APRS frame.\n");
}
}
if (ServerCommand) {
if (ServerCommand == 1) {
ComposeAprsFrame(AprsSettings.FirmwareVersion);
// Wait for 100ms before responding
sleep_ms(5000);
transmit();
sleep_ms(5000);
transmit();
sleep_ms(5000);
transmit();
sleep_ms(5000);
transmit();
}
ServerCommand = 0;
}
}
return 0;
}
/*
* Load settings from EEPROM
*/
bool LoadSettings()
{
printf("APRS settings:\n");
printf("My call: %s\n", AprsSettings.MyCall);
printf("Server call: %s\n", AprsSettings.ServerCall);
}
/*
* Initializes the LoRa module with the parameters set in config.h
*/
@ -95,8 +132,9 @@ void getPacketData(int packetLength)
/* Encode LoRa APRS frame: extract source call, digipeater path and data field. At the same time, check for data corruption
*
* If frame is a message from the server it returns the command from this server
*/
void encode_kiss ()
uint16_t decode_packet ()
{
int position = 0;
int cnt = 0;
@ -106,12 +144,18 @@ void encode_kiss ()
uint8_t aprs_source_address[10];
uint8_t aprs_digi_path[255];
uint8_t aprs_data_field[255];
uint8_t aprs_message[255];
uint8_t aprs_digis[10][10];
uint8_t aprs_acknowledge_number[255];
bool aprs_acknowledge_request = false;
uint16_t aprs_server_command = 0;
memset(aprs_source_address, 0, sizeof(aprs_source_address));
memset(aprs_digi_path, 0, sizeof(aprs_digi_path));
memset(aprs_data_field, 0, sizeof(aprs_data_field));
memset(aprs_message, 0, sizeof(aprs_message));
memset(aprs_digis, 0, sizeof(aprs_digis));
memset(aprs_acknowledge_number, 0, sizeof(aprs_acknowledge_number));
// Extract from address
cnt = 0;
@ -184,8 +228,202 @@ void encode_kiss ()
aprs_digis[number_of_digipeaters][cnt] = 0;
}
if (valid_apsr_data)
if (valid_apsr_data) {
// Check if packet comes from our server and if so, check if it is a message for us.
if ( !compare_strings(aprs_source_address, AprsSettings.ServerCall) ) {
if ( is_message_for_me(aprs_data_field, AprsSettings.MyCall) )
{
// Extract aprs message from data field
position=11;
while( aprs_data_field[position] != 0 )
{
aprs_message[position-11] = aprs_data_field[position];
position++;
}
// Extract command and acknowledge number (if present)
cnt = 0;
position = 0;
while( aprs_message[position] != 0 )
{
if ( aprs_message[position] == '{' ) {
aprs_acknowledge_number[cnt++] = ':';
while ( AprsSettings.ServerCall[cnt-1] != 0 )
{
aprs_acknowledge_number[cnt] = AprsSettings.ServerCall[cnt-1];
cnt++;
}
//Fill with spaces
while ( cnt<10 )
{
aprs_acknowledge_number[cnt++] = ' ';
}
aprs_acknowledge_number[cnt++] = ':';
aprs_acknowledge_number[cnt++] = 'a';
aprs_acknowledge_number[cnt++] = 'c';
aprs_acknowledge_number[cnt++] = 'k';
aprs_acknowledge_request = true;
}
// Calculate server command
if (!aprs_acknowledge_request) {
aprs_server_command = 10*aprs_server_command + aprs_message[position]-48;
}
position++;
if (aprs_acknowledge_request) {
aprs_acknowledge_number[cnt++] = aprs_message[position];
}
}
aprs_acknowledge_number[cnt] = 0;
}
}
printf("Source address: %s\nDigipeaters (%u): %s %s %s %s\nData: %s\n", aprs_source_address, number_of_digipeaters+1, aprs_digis[0], aprs_digis[1], aprs_digis[2], aprs_digis[3], aprs_data_field);
if (aprs_message[0])
{
printf("Message from server: %s (command %u)\n", aprs_message, aprs_server_command);
if (aprs_acknowledge_request) {
ComposeAprsFrame(aprs_acknowledge_number);
// Wait for 100ms before responding with acknowledge
sleep_ms(100);
transmit();
printf("Acknowledge request: %s\n", aprs_acknowledge_number);
}
}
}
else
printf("Error decoding APRS frame.");
return (aprs_server_command);
}
/*
* Checks if aprs datafield contains message and if message is for us
*
* Returns: 0 if datafield contains no message for us
* 1 if datafield contains a message for us
*/
bool is_message_for_me (uint8_t data[], uint8_t mycall[])
{
// A variable to iterate through the strings
int i=0;
if (data[0] == ':' && data[10] == ':')
{
while( i<9 && mycall[i] != 0 ) {
if (data[i+1] != mycall[i]) {
return (0);
}
i++;
}
return (1);
}
return (0);
}
int compare_strings(uint8_t a[], uint8_t b[])
{
// A variable to iterate through the strings
int i = 0;
while (a[i] == b[i])
{
// If either of the strings reaches the end
// we stop the loop
if (a[i] == '\0' || b[i] == '\0')
break;
i++;
}
// We check if both the strings have been compared
// till the end or not
// If the strings are compared till the end they are equal
if (a[i] == '\0' && b[i] == '\0')
return 0;
else
{
if(a[i] == '\0')
return -1*(b[i]);
else if(b[i] == '\0')
return a[i];
else
return (a[i]-b[i]);
}
}
void ComposeAprsFrame(uint8_t payload[])
{
uint16_t BufferPosition = 0;
uint16_t cnt = 0;
// APRS header
txBuffer[BufferPosition++] = '<';
txBuffer[BufferPosition++] = 0xff;
txBuffer[BufferPosition++] = 0x01;
while ( AprsSettings.MyCall[cnt] != 0 && BufferPosition<MTU )
{
txBuffer[BufferPosition++] = AprsSettings.MyCall[cnt];
cnt++;
}
txBuffer[BufferPosition++] = '>';
cnt=0;
while ( AprsSettings.Destination[cnt] != 0 && BufferPosition<MTU )
{
txBuffer[BufferPosition++] = AprsSettings.Destination[cnt];
cnt++;
}
if ( AprsSettings.Path1[0] != 0)
txBuffer[BufferPosition++] = ',';
cnt=0;
while ( AprsSettings.Path1[cnt] != 0 && BufferPosition<MTU )
{
txBuffer[BufferPosition++] = AprsSettings.Path1[cnt];
cnt++;
}
if ( AprsSettings.Path2[0] != 0)
txBuffer[BufferPosition++] = ',';
cnt=0;
while ( AprsSettings.Path2[cnt] != 0 && BufferPosition<MTU )
{
txBuffer[BufferPosition++] = AprsSettings.Path2[cnt];
cnt++;
}
txBuffer[BufferPosition++] = ':';
cnt=0;
while ( payload[cnt] != 0 && BufferPosition<MTU )
{
txBuffer[BufferPosition++] = payload[cnt];
cnt++;
}
printf("%s\n", txBuffer);
}
void transmit() {
uint16_t position = 0;
LoRa.beginPacket();
while( txBuffer[position] != 0 )
{
LoRa.write(txBuffer[position]);
position++;
}
LoRa.endPacket();
LoRa.receive();
}

Loading…
Cancel
Save