integrating aprs-is message decoder, sending ACK to messages, string to int converter for messages

master
Mateusz Lubecki 2024-04-25 22:14:25 +02:00
rodzic 428f6a2360
commit 012e2b3557
10 zmienionych plików z 271 dodań i 22 usunięć

Wyświetl plik

@ -13,6 +13,7 @@
#include "gsm/sim800c_tcpip.h"
#include "ax25.h"
#include "telemetry.h"
#include "message.h"
typedef enum aprsis_return {
@ -99,8 +100,11 @@ void aprsis_igate_to_aprsis(AX25Msg *msg, const char * callsign_with_ssid);
void aprsis_send_server_comm_counters(const char * callsign_with_ssid);
void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, uint16_t voltage);
void aprsis_send_gsm_status(const char * callsign_with_ssid);
void aprsis_send_ack_for_message(const message_t * const message);
#ifdef UNIT_TEST
char * aprsis_get_tx_buffer(void);
#endif
uint8_t aprsis_get_aprsis_logged(void);
void aprsis_debug_set_simulate_timeout(void);

Wyświetl plik

@ -44,6 +44,14 @@ inline uint32_t backup_reg_get_monitor(void) {
return REGISTER_MONITOR;
}
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_WX (1U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_BEACON (1U << 1U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_TELEMETRY (1U << 2U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_DESCR (1U << 3U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_IGATE (1U << 4U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_CNTRS (1U << 5U)
#define BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_LOGINSTRING (1U << 6U)
uint32_t backup_reg_get_configuration(void);
void backup_reg_set_configuration(uint32_t value);
void backup_reg_set_bits_configuration(uint32_t value);
@ -86,6 +94,7 @@ void backup_reg_increment_weather_measurements_check_reset(void);
void backup_reg_increment_dallas_degraded_reset(void);
void backup_reg_increment_is_rtc_ok_check_reset(void);
void backup_assert(uint32_t assert);
#endif /* BACKUP_REGISTERS_H_ */

Wyświetl plik

@ -4,6 +4,7 @@
#include <stdint.h>
#include "stored_configuration_nvm/config_data.h"
#include "message.h"
//!< Set immediately after waking up in RTC interrupt handler
#define RTE_MAIN_WOKEN_UP_RTC_INTERRUPT 1u
@ -14,6 +15,12 @@
//!< Set after everything was reinitialized from
#define RTE_MAIN_WOKEN_UP_EXITED 4u
extern message_t rte_main_received_message;
extern message_source_t rte_main_received_message_source;
//!< Trigger preparing and sending ACK
extern uint8_t rte_main_trigger_message_ack;
extern uint8_t rte_main_trigger_gsm_aprsis_counters_packet;
extern uint8_t rte_main_trigger_gsm_loginstring_packet;

Wyświetl plik

@ -8,6 +8,8 @@
#include "aprsis.h"
#include "etc/aprsis_config.h"
#include "text.h"
#include "backup_registers.h"
#include "aprs/status.h"
#include "aprs/message.h"
@ -41,7 +43,7 @@ gsm_sim800_state_t * aprsis_gsm_modem_state;
/**
* Buffer for sending packet to aprs-is
*/
char aprsis_packet_tx_buffer[APRSIS_TX_BUFFER_LN];
static char aprsis_packet_tx_buffer[APRSIS_TX_BUFFER_LN];
/**
* Lenght of buffer
@ -81,6 +83,16 @@ const char * aprsis_default_server_address;
*/
const char * aprsis_callsign_with_ssid;
/**
* Pointer to callsign from configuration
*/
const char * aprsis_callsign;
/**
* ssid from configuration
*/
uint8_t aprsis_ssid;
/**
* Lenght of APRS-IS server address string
*/
@ -193,13 +205,13 @@ char aprsis_login_string_reveived[APRSIS_LOGIN_STRING_RECEIVED_LN];
* @param message_ln
* @return position at which content of message starts
*/
STATIC int aprsis_check_is_message(const uint8_t * const message, const uint16_t message_ln) {
STATIC uint16_t aprsis_check_is_message(const uint8_t * const message, const uint16_t message_ln) {
// example message
// Details:"SP8EBC>APX216,TCPIP*,qAC,NINTH::SR9WXZ :tedt{0s}\r\n", '\0' <repeats 715 times>
// go through a buffer and look for double ':'
int message_start_position = 0;
uint16_t message_start_position = 0;
for (int i = 0; i < message_ln; i++) {
const uint8_t * this_character = message + i;
@ -233,18 +245,46 @@ STATIC void aprsis_receive_callback(srl_context_t* srl_context) {
if (srl_context->srl_rx_state == SRL_RX_DONE) {
// check if this is keepalive message
if (*buffer == '#') {
// set last timestamps
aprsis_last_keepalive_ts = main_get_master_time();
aprsis_last_keepalive_long_ts = main_get_master_time();
// increase received keepalive counter
aprsis_keepalive_received_counter++;
// restart receiving from serial port
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
}
else if (aprsis_check_is_message(buffer, message_ln) == 1) {
}
else {
// check if this is an aprs message
const int message_position = aprsis_check_is_message(buffer, message_ln);
// if yes try to decode it
if (message_position != 0) {
// prevent overwriting message received from radio channel if it hasn't been serviced yet
if (rte_main_received_message_source == MESSAGE_SOURCE_UNINITIALIZED) {
// if decoding was successfull
if (message_decode(buffer, message_ln, message_position, MESSAGE_SOURCE_APRSIS, &rte_main_received_message) == 0) {
// check if it is for me
if (message_is_for_me(aprsis_callsign, aprsis_ssid, &rte_main_received_message) == 0) {
// set a source of this message
rte_main_received_message_source = MESSAGE_SOURCE_APRSIS;
// trigger preparing ACK
rte_main_trigger_message_ack = 1;
}
}
}
}
else {
;
}
aprsis_another_received_counter++;
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
@ -253,6 +293,18 @@ STATIC void aprsis_receive_callback(srl_context_t* srl_context) {
}
}
/**
*
* @param context
* @param gsm_modem_state
* @param callsign
* @param ssid
* @param passcode
* @param default_server
* @param default_port
* @param reset_on_timeout
* @param callsign_with_ssid
*/
void aprsis_init(
srl_context_t * context,
gsm_sim800_state_t * gsm_modem_state,
@ -285,6 +337,10 @@ void aprsis_init(
aprsis_reset_on_timeout = reset_on_timeout;
aprsis_callsign = callsign;
aprsis_ssid = ssid;
}
/**
@ -574,6 +630,11 @@ void aprsis_send_wx_frame(
return;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_WX);
}
aprsis_tx_counter++;
float max_wind_speed = 0.0f, temp = 0.0f;
@ -652,6 +713,11 @@ void aprsis_send_beacon(
return;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_BEACON);
}
aprsis_tx_counter++;
aprsis_packet_tx_message_size = snprintf(
@ -771,6 +837,8 @@ void aprsis_prepare_telemetry(
/**
* Sends to APRS-IS prepared telemetry frame prepared in advance
* @param async
* @param callsign_with_ssid
*/
void aprsis_send_telemetry(uint8_t async, const char * callsign_with_ssid) {
@ -784,6 +852,11 @@ void aprsis_send_telemetry(uint8_t async, const char * callsign_with_ssid) {
return;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_TELEMETRY);
}
aprsis_tx_counter++;
aprsis_packet_tx_message_size = snprintf(
@ -843,6 +916,11 @@ telemetry_description_t aprsis_send_description_telemetry(uint8_t async,
return next;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_DESCR);
}
telemetry_create_description_string(config_basic, what, main_own_aprs_msg, OWN_APRS_MSG_LN);
aprsis_tx_counter++;
@ -881,6 +959,11 @@ void aprsis_igate_to_aprsis(AX25Msg *msg, const char * callsign_with_ssid) {
return;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_IGATE);
}
aprsis_igated_counter++;
// prepare buffer for message
@ -962,6 +1045,11 @@ void aprsis_send_server_comm_counters(const char * callsign_with_ssid) {
return;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_CNTRS);
}
memset (aprsis_packet_tx_buffer, 0x00, APRSIS_TX_BUFFER_LN);
aprsis_tx_counter++;
@ -988,6 +1076,11 @@ void aprsis_send_loginstring(const char * callsign_with_ssid, uint8_t rtc_ok, ui
return;
}
if (gsm_sim800_tcpip_tx_busy() == 1) {
// will die here
backup_assert(BACKUP_REG_ASSERT_CONCURENT_ACCES_APRSIS_LOGINSTRING);
}
memset (aprsis_packet_tx_buffer, 0x00, APRSIS_TX_BUFFER_LN);
aprsis_tx_counter++;
@ -1029,9 +1122,24 @@ void aprsis_send_gsm_status(const char * callsign_with_ssid) {
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);
}
/**
*
* @param message
*/
void aprsis_send_ack_for_message(const message_t * const message) {
aprsis_packet_tx_message_size = message_create_ack_for((uint8_t*)aprsis_packet_tx_buffer, APRSIS_TX_BUFFER_LN - 1, message, MESSAGE_SOURCE_APRSIS);
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);
rte_main_received_message_source = MESSAGE_SOURCE_UNINITIALIZED;
}
#ifdef UNIT_TEST
char * aprsis_get_tx_buffer(void) {
return aprsis_packet_tx_buffer;
}
#endif
uint8_t aprsis_get_aprsis_logged(void) {
return aprsis_logged;

Wyświetl plik

@ -17,11 +17,13 @@
#define REGISTER_LAST_SLTIM RTC->BKP6R
#define REGISTER_PACKET_COUNTERS RTC->BKP7R
#define REGISTER_RESET_CHECK_FAIL RTC->BKP8R
#define REGISTER_ASSERT RTC->BKP9R
#endif
#define BACKUP_REG_INHIBIT_PWR_SWITCH_PERIODIC_H 1u
#define BACKUP_REG_ALL_PWRSAVE_STATES_BITMASK (0xFFu << 2)
// backup registers (ParaTNC)
// 0 ->
// 2 -> boot and hard fault count
@ -41,6 +43,7 @@
// 6 -> last sleep time
// 7 -> weather and telemetry timers & counters
// 8 -> counters of resets caused by validation checks failures
// 9 -> assert register
// 7th register map
// xxxxyyAA - telemetry frames counter
@ -597,6 +600,7 @@ void backup_reg_set_packet_counters(uint8_t beacon_counter, uint8_t meteo_counte
}
void backup_reg_increment_aprsis_check_reset(void) {
#ifdef PARAMETEO
// REGISTER_RESET_CHECK_FAIL
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
@ -617,9 +621,11 @@ void backup_reg_increment_aprsis_check_reset(void) {
REGISTER_RESET_CHECK_FAIL = reg_value;
backup_reg_lock();
#endif
}
void backup_reg_increment_weather_measurements_check_reset(void) {
#ifdef PARAMETEO
// REGISTER_RESET_CHECK_FAIL
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
@ -640,9 +646,11 @@ void backup_reg_increment_weather_measurements_check_reset(void) {
REGISTER_RESET_CHECK_FAIL = reg_value;
backup_reg_lock();
#endif
}
void backup_reg_increment_dallas_degraded_reset(void) {
#ifdef PARAMETEO
// REGISTER_RESET_CHECK_FAIL
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
@ -663,9 +671,11 @@ void backup_reg_increment_dallas_degraded_reset(void) {
REGISTER_RESET_CHECK_FAIL = reg_value;
backup_reg_lock();
#endif
}
void backup_reg_increment_is_rtc_ok_check_reset(void) {
#ifdef PARAMETEO
// REGISTER_RESET_CHECK_FAIL
volatile uint32_t reg_value = REGISTER_RESET_CHECK_FAIL;
@ -686,4 +696,17 @@ void backup_reg_increment_is_rtc_ok_check_reset(void) {
REGISTER_RESET_CHECK_FAIL = reg_value;
backup_reg_lock();
#endif
}
void backup_assert(uint32_t assert) {
#ifdef PARAMETEO
backup_reg_unclock();
REGISTER_ASSERT |= assert;
backup_reg_lock();
NVIC_SystemReset();
#endif
}

Wyświetl plik

@ -1246,14 +1246,27 @@ int main(int argc, char* argv[]){
// receive callback for communicatio with the modem
gsm_sim800_rx_done_event_handler(main_gsm_srl_ctx_ptr, &main_gsm_state);
//srl_reset(main_gsm_srl_ctx_ptr);
}
if (main_gsm_srl_ctx_ptr->srl_tx_state == SRL_TX_IDLE) {
gsm_sim800_tx_done_event_handler(main_gsm_srl_ctx_ptr, &main_gsm_state);
}
if (rte_main_trigger_message_ack == 1) {
if (rte_main_received_message_source == MESSAGE_SOURCE_APRSIS && gsm_sim800_tcpip_tx_busy() == 0) {
rte_main_trigger_message_ack = 0;
aprsis_send_ack_for_message(&rte_main_received_message);
rte_main_received_message_source == MESSAGE_SOURCE_UNINITIALIZED;
}
else if (rte_main_received_message_source == MESSAGE_SOURCE_RADIO) {
}
}
if (rte_main_trigger_gsm_status == 1 && gsm_sim800_tcpip_tx_busy() == 0) {
rte_main_trigger_gsm_status = 0;

Wyświetl plik

@ -17,7 +17,13 @@ uint8_t rte_main_trigger_status = 0;
uint8_t rte_main_trigger_wx_packet = 0;
message_t rte_main_received_message;
message_source_t rte_main_received_message_source;
#ifdef PARAMETEO
//!< Trigger preparing and sending ACK
uint8_t rte_main_trigger_message_ack = 0;
uint8_t rte_main_trigger_gsm_aprsis_counters_packet = 0;
//!< Trigger sending status packet with received APRS is login string

Wyświetl plik

@ -25,7 +25,6 @@ int variant_validate_is_within_ram(void * address) {
}
int variant_validate_is_within_flash(void * address) {
uint32_t addr_value = (uint32_t)address;
if (addr_value > FLASH_BASE &&

Wyświetl plik

@ -22,9 +22,11 @@ typedef struct message_t {
}message_t;
typedef enum message_source_t {
MESSAGE_SOURCE_APRSIS,
MESSAGE_SOURCE_RADIO
MESSAGE_SOURCE_UNINITIALIZED = 0x0,
MESSAGE_SOURCE_APRSIS = 0x1,
MESSAGE_SOURCE_APRSIS_HEXCNTR = 0x2,
MESSAGE_SOURCE_RADIO = 0x11,
MESSAGE_SOURCE_RADIO_HEXCNTR = 0x12
}message_source_t;
/**
@ -36,7 +38,7 @@ typedef enum message_source_t {
* @param output parsed APRS message content
* @return zero if message has been found and decoded, non zero if parsing failed
*/
uint8_t message_decode_from_aprsis(const uint8_t * const message, const uint16_t message_ln, uint16_t content_position, message_source_t src, message_t * output);
uint8_t message_decode(const uint8_t * const message, const uint16_t message_ln, uint16_t content_position, message_source_t src, message_t * output);
/**
*
@ -44,7 +46,7 @@ uint8_t message_decode_from_aprsis(const uint8_t * const message, const uint16_t
* @param message
* @return zero if this is a message to us, non zero otherwise
*/
uint8_t message_is_for_me(config_data_basic_t * config_data, const message_t * const message);
uint8_t message_is_for_me(const char * const callsign, const uint8_t ssid, const message_t * const message);
/**
*
@ -53,6 +55,6 @@ uint8_t message_is_for_me(config_data_basic_t * config_data, const message_t * c
* @param message
* @param src how this message has been received
*/
void message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln, const message_t * const message, const message_source_t src);
int message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln, const message_t * const message, const message_source_t src);
#endif /* INCLUDE_APRS_MESSAGE_H_ */

Wyświetl plik

@ -6,9 +6,16 @@
*/
#include "message.h"
#include "variant.h"
#include "string.h"
#include "stdio.h"
#ifdef UNIT_TEST
#define STATIC
#else
#define STATIC static
#endif
#define MESSAGE_RECIPIENT_FIELD_SIZE 9
#define MESSAGE_SSID_CHARS_LN 2
@ -27,8 +34,77 @@
#define MESSAGE_ACK_CURRENT_POS (char*)(out_buffer + current_pos)
/**
* Lookup table used to string-to-int conversion for HEX strings. Value of 0x30 should be
* subtracted from ASCII scancode and this value should be used to intex this table
*/
static const int8_t message_atoi_lookup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-1, -1, -1, -1, -1, -1, -1,
10, 11, 12, 13, 14, 15,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1,
10, 11, 12, 13, 14, 15};
/**
* Table used
*/
static char message_atoi_buffer[MESSAGE_ATOI_BUFFER];
/**
* Convert string with message number to integer, with automatic detection of decimal or hex base. It operates
* only on positive integers up to 32 bit wide.
* @param string
* @param string_ln
* @param output optional pointer to message structure when output will be also put
* @return unsigned integer with decoded number
*/
STATIC uint32_t message_atoi_message_counter(const uint8_t const * string, uint8_t string_ln, message_t * output) {
uint32_t sum = 0u;
int8_t conversion_table[6];
int8_t is_hex = 0;
if (variant_validate_is_within_ram(string) == 1 && string_ln <= 6) {
memset(conversion_table, 0x00, string_ln);
for (int8_t i = string_ln; i >= 0; i--) {
const uint8_t index = *(string + i - 1) - 0x30u;
conversion_table[string_ln - i] = message_atoi_lookup[index];
if (*(string + i) > '9') {
is_hex = 1;
}
}
if (is_hex == 1) {
sum = (conversion_table[0]);
sum += (conversion_table[1] * 0x10);
sum += (conversion_table[2] * 0x100);
sum += (conversion_table[3] * 0x1000);
sum += (conversion_table[4] * 0x10000);
sum += (conversion_table[5] * 0x100000);
}
else {
sum = (conversion_table[0]);
sum += (conversion_table[1] * 10);
sum += (conversion_table[2] * 100);
sum += (conversion_table[3] * 1000);
sum += (conversion_table[4] * 10000);
sum += (conversion_table[5] * 100000);
}
}
if (variant_validate_is_within_ram(output) == 1) {
output->number = sum & 0xFFu;
}
return sum;
}
/**
* Decode received data to look for an APRS message and put it into a structure
* @param message pointer to data received from APRS-IS
@ -37,7 +113,7 @@ static char message_atoi_buffer[MESSAGE_ATOI_BUFFER];
* @param output parsed APRS message content
* @return zero if message has been found and decoded, non zero if parsing failed
*/
uint8_t message_decode_from_aprsis(const uint8_t * const message, const uint16_t message_ln, uint16_t content_position, message_source_t src, message_t * output) {
uint8_t message_decode(const uint8_t * const message, const uint16_t message_ln, uint16_t content_position, message_source_t src, message_t * output) {
// example message:: SP8EBC>APX216,TCPIP*,qAC,NINTH::SR9WXZ :tedt{0s}\r\n
@ -271,11 +347,11 @@ uint8_t message_decode_from_aprsis(const uint8_t * const message, const uint16_t
* @param message
* @return zero if this is a message to us, non zero otherwise
*/
uint8_t message_is_for_me(config_data_basic_t * config_data, const message_t * const message)
uint8_t message_is_for_me(const char * const callsign, const uint8_t ssid, const message_t * const message)
{
const int callsign = strncmp(config_data->callsign, message->to.call, 6);
const int _callsign = strncmp(callsign, message->to.call, 6);
if (callsign == 0 && (config_data->ssid == message->to.ssid)) {
if (_callsign == 0 && (ssid == message->to.ssid)) {
return 0;
}
else {
@ -290,7 +366,7 @@ uint8_t message_is_for_me(config_data_basic_t * config_data, const message_t * c
* @param message
* @param src how this message has been received
*/
void message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln, const message_t * const message, const message_source_t src)
int message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln, const message_t * const message, const message_source_t src)
{
int current_pos = 0;
@ -352,10 +428,12 @@ void message_create_ack_for(uint8_t * out_buffer, const uint16_t out_buffer_ln,
current_pos += 9;
// then put 'ackXX' where X is message number
current_pos += snprintf(MESSAGE_ACK_CURRENT_POS, MESSAGE_ACK_REMAINING_BUF, ":ack%d", message->number);
current_pos += snprintf(MESSAGE_ACK_CURRENT_POS, MESSAGE_ACK_REMAINING_BUF, ":ack%d\r\n", message->number);
}
else {
}
return current_pos;
}