Skip to content

Commit 5315579

Browse files
committed
Add forceTalkerId, forceRmcCog, removeRmcNavStat
1 parent 83d4d87 commit 5315579

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

Firmware/RTK_Everywhere/Tasks.ino

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,121 @@ void gnssReadTask(void *e)
576576
vTaskDelete(NULL);
577577
}
578578

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+
579694
// Call back from within parser, for end of message
580695
// Process a complete message incoming from parser
581696
// 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)
642757
latestGPGGA[parse->length] = 0; // NULL terminate
643758
if ((strlen(latestGPGGA) > 10) && (latestGPGGA[strlen(latestGPGGA) - 2] == '\r'))
644759
latestGPGGA[strlen(latestGPGGA) - 2] = 0; // Truncate the \r\n
760+
forceTalkerId("P",latestGPGGA,latestNmeaMaxLen);
645761
}
646762
else
647763
systemPrintf("Increase latestNmeaMaxLen to > %d\r\n", parse->length);
@@ -654,6 +770,9 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
654770
latestGPRMC[parse->length] = 0; // NULL terminate
655771
if ((strlen(latestGPRMC) > 10) && (latestGPRMC[strlen(latestGPRMC) - 2] == '\r'))
656772
latestGPRMC[strlen(latestGPRMC) - 2] = 0; // Truncate the \r\n
773+
forceTalkerId("P",latestGPRMC,latestNmeaMaxLen);
774+
forceRmcCog(latestGPRMC,latestNmeaMaxLen);
775+
removeRmcNavStat(latestGPRMC,latestNmeaMaxLen);
657776
}
658777
else
659778
systemPrintf("Increase latestNmeaMaxLen to > %d\r\n", parse->length);
@@ -666,6 +785,7 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
666785
latestGPGST[parse->length] = 0; // NULL terminate
667786
if ((strlen(latestGPGST) > 10) && (latestGPGST[strlen(latestGPGST) - 2] == '\r'))
668787
latestGPGST[strlen(latestGPGST) - 2] = 0; // Truncate the \r\n
788+
forceTalkerId("P",latestGPGST,latestNmeaMaxLen);
669789
}
670790
else
671791
systemPrintf("Increase latestNmeaMaxLen to > %d\r\n", parse->length);

0 commit comments

Comments
 (0)