11#include " aprs_manager.h"
22#include " ../config/config.h"
3+ #include " ../core/metadata.h" // NEW: Pulls dynamic version
34#include " ../hw/sensor.h"
4- #include " ../hw/led_rgb.h" // NEW: RGB LED controller inclusion
5+ #include " ../hw/led_rgb.h"
56#include < Arduino.h>
67#include < WiFi.h>
78#include < WiFiClient.h>
@@ -25,7 +26,6 @@ namespace services {
2526 uint32_t AprsManager::last_tx_time = 0 ;
2627 static uint32_t loop_last_beacon_millis = 0 ;
2728
28- // TX queue buffers shifted to the heap
2929 static char * tx_msg_queue = nullptr ;
3030 static bool tx_msg_pending = false ;
3131
@@ -59,21 +59,19 @@ namespace services {
5959 void AprsManager::clear_msg_dirty () { msg_dirty = false ; }
6060
6161 void AprsManager::trigger_manual_beacon () {
62- loop_last_beacon_millis = 0 ;
62+ loop_last_beacon_millis = 0 ;
6363 }
6464
6565 void AprsManager::send_message (const char * target, const char * message, bool silent) {
6666 auto & cfg = config::get ();
6767 if (!connected || !tx_msg_queue) return ;
6868 if (strlen (target) == 0 || strlen (message) == 0 ) return ;
6969
70- // Force Sender to Uppercase
7170 char src_call[16 ];
7271 if (cfg.aprs_ssid == 0 ) snprintf (src_call, sizeof (src_call), " %s" , cfg.callsign );
7372 else snprintf (src_call, sizeof (src_call), " %s-%d" , cfg.callsign , cfg.aprs_ssid );
7473 for (int i = 0 ; src_call[i]; i++) src_call[i] = toupper (src_call[i]);
7574
76- // Force Target to Uppercase & strict 9-character padding
7775 char padded_target[10 ] = " " ;
7876 for (size_t i = 0 ; i < 9 && target[i] != ' \0 ' ; i++) {
7977 padded_target[i] = toupper (target[i]);
@@ -102,8 +100,8 @@ namespace services {
102100
103101 for (size_t i = 0 ; i < station_count - 1 ; i++) {
104102 for (size_t j = 0 ; j < station_count - i - 1 ; j++) {
105- bool swap_needed = ascending ?
106- (stations[j].distance_km > stations[j+1 ].distance_km ) :
103+ bool swap_needed = ascending ?
104+ (stations[j].distance_km > stations[j+1 ].distance_km ) :
107105 (stations[j].distance_km < stations[j+1 ].distance_km );
108106
109107 if (swap_needed) {
@@ -117,7 +115,7 @@ namespace services {
117115 }
118116
119117 void AprsManager::calc_distance_bearing (float lat1, float lon1, float lat2, float lon2, float & out_dist, int & out_bearing) {
120- float R = 6371 .0f ;
118+ float R = 6371 .0f ;
121119 float dLat = (lat2 - lat1) * PI / 180 .0f ;
122120 float dLon = (lon2 - lon1) * PI / 180 .0f ;
123121 float rLat1 = lat1 * PI / 180 .0f ;
@@ -152,7 +150,7 @@ namespace services {
152150 int lon_deg = (int )lon;
153151 float lon_min = (lon - lon_deg) * 60 .0f ;
154152
155- snprintf (out_str, 24 , " %02d%05.2f%c%c%03d%05.2f%c%c" ,
153+ snprintf (out_str, 24 , " %02d%05.2f%c%c%03d%05.2f%c%c" ,
156154 lat_deg, lat_min, lat_dir, table, lon_deg, lon_min, lon_dir, symbol);
157155 }
158156
@@ -200,7 +198,7 @@ namespace services {
200198 stations[target_idx].bearing_deg = brg;
201199 stations[target_idx].last_seen_millis = millis ();
202200
203- if (symbol_char[0 ] == ' [' && table_char[0 ] == ' /' ) strncpy (stations[target_idx].type , " Runner" , 15 );
201+ if (symbol_char[0 ] == ' [' && table_char[0 ] == ' /' ) strncpy (stations[target_idx].type , " Runner" , 15 );
204202 else if (symbol_char[0 ] == ' -' && table_char[0 ] == ' /' ) strncpy (stations[target_idx].type , " Fixed Base" , 15 );
205203 else if (symbol_char[0 ] == ' &' && table_char[0 ] == ' I' ) strncpy (stations[target_idx].type , " Gateway" , 15 );
206204 else if (symbol_char[0 ] == ' Y' && table_char[0 ] == ' \\ ' ) strncpy (stations[target_idx].type , " Radios/APRS" , 15 );
@@ -225,8 +223,8 @@ namespace services {
225223 char lat_str[9 ] = {0 };
226224 char lon_str[10 ] = {0 };
227225
228- strncpy (lat_str, info + 1 , 8 );
229- strncpy (lon_str, info + 10 , 9 );
226+ strncpy (lat_str, info + 1 , 8 );
227+ strncpy (lon_str, info + 10 , 9 );
230228
231229 char table_char[2 ] = { info[9 ], ' \0 ' };
232230 char symbol_char[2 ] = { info[18 ], ' \0 ' };
@@ -248,16 +246,12 @@ namespace services {
248246
249247 const char * cmt = (strlen (info) > 19 ) ? (info + 19 ) : " " ;
250248 update_or_add_station (call, dec_lat, dec_lon, table_char, symbol_char, cmt);
251-
252- // NEW: Trigger a 30ms Cyan pulse to confirm standard background data ingress
253- hw::led_rgb::trigger_traffic_pulse ();
254249 }
255250
256251 void AprsManager::parse_incoming_message (const char * call, const char * info) {
257252 auto & cfg = config::get ();
258253 if (strlen (info) < 11 || info[0 ] != ' :' ) return ;
259254
260- // Extract the 9-character destination from the packet and trim it
261255 char rx_target[10 ];
262256 memcpy (rx_target, info + 1 , 9 );
263257 rx_target[9 ] = ' \0 ' ;
@@ -266,29 +260,25 @@ namespace services {
266260 else break ;
267261 }
268262
269- // Must match our base callsign (case-insensitive) to catch any SSID variant
270263 if (strncasecmp (rx_target, cfg.callsign , strlen (cfg.callsign )) != 0 ) return ;
271264
272265 if (info[10 ] == ' :' ) {
273266 char msg_body[64 ];
274267 strncpy (msg_body, info + 11 , 63 );
275268 msg_body[63 ] = ' \0 ' ;
276269
277- // Check for Message ID requiring an ACK
278270 char * ack_start = strrchr (msg_body, ' {' );
279271 if (ack_start) {
280- *ack_start = ' \0 ' ; // Strip the '{ID' from the display string
272+ *ack_start = ' \0 ' ;
281273 char ack_id[10 ];
282274 strncpy (ack_id, ack_start + 1 , 9 );
283275 ack_id[9 ] = ' \0 ' ;
284276
285- // Send silent Auto-ACK directly back to the sender
286277 char ack_payload[16 ];
287278 snprintf (ack_payload, sizeof (ack_payload), " ack%s" , ack_id);
288279 send_message (call, ack_payload, true );
289280 }
290281
291- // Hide incoming network ACKs so they don't clutter the user's chat screen
292282 if (strncasecmp (msg_body, " ack" , 3 ) == 0 ) return ;
293283
294284 if (message_count < 10 ) {
@@ -302,7 +292,6 @@ namespace services {
302292 }
303293 msg_dirty = true ;
304294
305- // Inbound directed radio transmission alert! Trigger 3s intense White/Magenta Strobe
306295 hw::led_rgb::trigger_priority_strobe ();
307296 }
308297 }
@@ -313,7 +302,7 @@ namespace services {
313302 char * colon = strchr (line, ' :' );
314303 if (!colon) return ;
315304
316- *colon = ' \0 ' ;
305+ *colon = ' \0 ' ;
317306 char * header = line;
318307 char * info = colon + 1 ;
319308
@@ -327,7 +316,7 @@ namespace services {
327316 } else if (info[0 ] == ' !' || info[0 ] == ' =' || info[0 ] == ' @' || info[0 ] == ' /' ) {
328317 const char * coord_start = info;
329318 if (info[0 ] == ' @' || info[0 ] == ' /' ) {
330- if (strlen (info) > 8 ) coord_start = info + 7 ;
319+ if (strlen (info) > 8 ) coord_start = info + 7 ;
331320 }
332321 parse_uncompressed_position (callsign, coord_start);
333322 }
@@ -353,11 +342,13 @@ namespace services {
353342 if (cfg.aprs_ssid == 0 ) snprintf (src_call, sizeof (src_call), " %s" , cfg.callsign );
354343 else snprintf (src_call, sizeof (src_call), " %s-%d" , cfg.callsign , cfg.aprs_ssid );
355344
356- snprintf (login, sizeof (login), " user %s pass %s vers QRPickle 1.0 filter r/%.2f/%.2f/50 p/%s\r\n " ,
357- src_call, cfg.aprs_passcode , cfg.lat , cfg.lon , cfg.callsign );
345+ // DYNAMIC VERSION INSERTION
346+ snprintf (login, sizeof (login), " user %s pass %s vers %s %s filter r/%.2f/%.2f/50 p/%s\r\n " ,
347+ src_call, cfg.aprs_passcode , meta::FW_NAME , meta::FW_VERSION , cfg.lat , cfg.lon , cfg.callsign );
348+
358349 client.print (login);
359350 connected = true ;
360- loop_last_beacon_millis = 0 ;
351+ loop_last_beacon_millis = 0 ;
361352 } else {
362353 vTaskDelay (pdMS_TO_TICKS (5000 ));
363354 continue ;
@@ -376,7 +367,7 @@ namespace services {
376367 else snprintf (src_call, sizeof (src_call), " %s-%d" , cfg.callsign , cfg.aprs_ssid );
377368
378369 char beacon[160 ];
379- snprintf (beacon, sizeof (beacon), " %s>APRS,TCPIP*:=%s%s\r\n " ,
370+ snprintf (beacon, sizeof (beacon), " %s>APRS,TCPIP*:=%s%s\r\n " ,
380371 src_call, coord_str, dynamic_cmt);
381372
382373 client.print (beacon);
@@ -388,7 +379,7 @@ namespace services {
388379
389380 if (tx_msg_pending && connected) {
390381 client.print (tx_msg_queue);
391- client.flush ();
382+ client.flush ();
392383 Serial.printf (" [APRS-TX] Hardware flushed packet to network: %s" , tx_msg_queue);
393384 tx_msg_pending = false ;
394385 }
@@ -410,4 +401,4 @@ namespace services {
410401 connected = false ;
411402 vTaskDelete (NULL );
412403 }
413- } // namespace services
404+ } // namespace services
0 commit comments