@@ -576,6 +576,121 @@ void gnssReadTask(void *e)
576
576
vTaskDelete (NULL );
577
577
}
578
578
579
+ // Force the NMEA Talker ID - if needed
580
+ void forceTalkerId (const char *Id, char *msg, size_t maxLen)
581
+ {
582
+ if (msg[2 ] == *Id)
583
+ return ; // Nothing to do
584
+
585
+ char oldTalker = msg[2 ];
586
+ msg[2 ] = *Id; // Force the Talker ID
587
+
588
+ // Update the checksum: XOR chars between '$' and '*'
589
+ size_t len = 1 ;
590
+ uint8_t csum = 0 ;
591
+ while ((len < maxLen) && (msg[len] != ' *' ))
592
+ csum = csum ^ msg[len++];
593
+
594
+ if (len >= (maxLen - 3 ))
595
+ {
596
+ // Something went horribly wrong. Restore the Talker ID
597
+ msg[2 ] = oldTalker;
598
+ return ;
599
+ }
600
+
601
+ len++; // Point at the checksum and update it
602
+ sprintf (&msg[len], " %02X" , csum);
603
+ }
604
+
605
+ // Force the RMC COG entry - if needed
606
+ void forceRmcCog (char *msg, size_t maxLen)
607
+ {
608
+ const char *noCog = " 0.0" ;
609
+
610
+ if (strstr (msg, " RMC" ) == nullptr )
611
+ return ; // Nothing to do
612
+
613
+ if (maxLen < (strlen (msg) + strlen (noCog)))
614
+ return ; // No room for the COG!
615
+
616
+ // Find the start of COG ("Track made good") - after the 8th comma
617
+ int numCommas = 0 ;
618
+ size_t len = 0 ;
619
+ while ((numCommas < 8 ) && (len < maxLen))
620
+ {
621
+ if (msg[len++] == ' ,' )
622
+ numCommas++;
623
+ }
624
+
625
+ if (len >= maxLen) // Something went horribly wrong
626
+ return ;
627
+
628
+ // If the next char is not a ',' - there's nothing to do
629
+ if (msg[len] != ' ,' )
630
+ return ;
631
+
632
+ // If the next char is a ',' - add "0.0" manually
633
+ // Start by creating space for the "0.0"
634
+ for (size_t i = strlen (msg); i > len; i--) // Work backwards from the NULL
635
+ msg[i + strlen (noCog)] = msg[i];
636
+
637
+ // Now insert the "0.0"
638
+ memcpy (&msg[len], noCog, strlen (noCog));
639
+
640
+ // Update the checksum: XOR chars between '$' and '*'
641
+ len = 1 ;
642
+ uint8_t csum = 0 ;
643
+ while ((len < maxLen) && (msg[len] != ' *' ))
644
+ csum = csum ^ msg[len++];
645
+ len++; // Point at the checksum and update it
646
+ sprintf (&msg[len], " %02X" , csum);
647
+ }
648
+
649
+ // Remove the RMC Navigational Status field - if needed
650
+ void removeRmcNavStat (char *msg, size_t maxLen)
651
+ {
652
+ if (strstr (msg, " RMC" ) == nullptr )
653
+ return ; // Nothing to do
654
+
655
+ // Find the start of Nav Stat - at the 13th comma
656
+ int numCommas = 0 ;
657
+ size_t len = 0 ;
658
+ while ((numCommas < 13 ) && (msg[len] != ' *' ) && (len < maxLen))
659
+ {
660
+ if (msg[len++] == ' ,' )
661
+ numCommas++;
662
+ }
663
+
664
+ if (len >= (maxLen - 3 )) // Something went horribly wrong
665
+ return ;
666
+
667
+ // If the next char is '*' - there's nothing to do
668
+ if ((msg[len] == ' *' ) || (numCommas < 13 ))
669
+ return ;
670
+
671
+ // Find the asterix. (NavStatus should be a single char)
672
+ size_t asterix = len;
673
+ len--;
674
+
675
+ while ((msg[asterix] != ' *' ) && (asterix < maxLen))
676
+ asterix++;
677
+
678
+ if (msg[asterix] != ' *' ) // Something went horribly wrong
679
+ return ;
680
+
681
+ // Delete the NavStat
682
+ for (size_t i = 0 ; i < (strlen (msg) + 1 - asterix); i++) // Copy the * CSUM NULL
683
+ msg[len + i] = msg[asterix + i];
684
+
685
+ // Update the checksum: XOR chars between '$' and '*'
686
+ len = 1 ;
687
+ uint8_t csum = 0 ;
688
+ while ((len < maxLen) && (msg[len] != ' *' ))
689
+ csum = csum ^ msg[len++];
690
+ len++; // Point at the checksum and update it
691
+ sprintf (&msg[len], " %02X" , csum);
692
+ }
693
+
579
694
// Call back from within parser, for end of message
580
695
// Process a complete message incoming from parser
581
696
// If we get a complete NMEA/UBX/RTCM message, pass on to SD/BT/TCP/UDP interfaces
@@ -642,6 +757,7 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
642
757
latestGPGGA[parse->length ] = 0 ; // NULL terminate
643
758
if ((strlen (latestGPGGA) > 10 ) && (latestGPGGA[strlen (latestGPGGA) - 2 ] == ' \r ' ))
644
759
latestGPGGA[strlen (latestGPGGA) - 2 ] = 0 ; // Truncate the \r\n
760
+ forceTalkerId (" P" ,latestGPGGA,latestNmeaMaxLen);
645
761
}
646
762
else
647
763
systemPrintf (" Increase latestNmeaMaxLen to > %d\r\n " , parse->length );
@@ -654,6 +770,9 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
654
770
latestGPRMC[parse->length ] = 0 ; // NULL terminate
655
771
if ((strlen (latestGPRMC) > 10 ) && (latestGPRMC[strlen (latestGPRMC) - 2 ] == ' \r ' ))
656
772
latestGPRMC[strlen (latestGPRMC) - 2 ] = 0 ; // Truncate the \r\n
773
+ forceTalkerId (" P" ,latestGPRMC,latestNmeaMaxLen);
774
+ forceRmcCog (latestGPRMC,latestNmeaMaxLen);
775
+ removeRmcNavStat (latestGPRMC,latestNmeaMaxLen);
657
776
}
658
777
else
659
778
systemPrintf (" Increase latestNmeaMaxLen to > %d\r\n " , parse->length );
@@ -666,6 +785,7 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
666
785
latestGPGST[parse->length ] = 0 ; // NULL terminate
667
786
if ((strlen (latestGPGST) > 10 ) && (latestGPGST[strlen (latestGPGST) - 2 ] == ' \r ' ))
668
787
latestGPGST[strlen (latestGPGST) - 2 ] = 0 ; // Truncate the \r\n
788
+ forceTalkerId (" P" ,latestGPGST,latestNmeaMaxLen);
669
789
}
670
790
else
671
791
systemPrintf (" Increase latestNmeaMaxLen to > %d\r\n " , parse->length );
0 commit comments