Add setUTCTimeAssistance. Change pushAssistNowData to const uint8_t * with String helpers.
This commit is contained in:
@@ -91,6 +91,7 @@ checkCallbacks KEYWORD2
|
||||
pushRawData KEYWORD2
|
||||
|
||||
pushAssistNowData KEYWORD2
|
||||
setUTCTimeAssistance KEYWORD2
|
||||
|
||||
setFileBufferSize KEYWORD2
|
||||
getFileBufferSize KEYWORD2
|
||||
|
||||
@@ -3979,14 +3979,43 @@ bool SFE_UBLOX_GNSS::pushRawData(uint8_t *dataBytes, size_t numDataBytes, bool s
|
||||
}
|
||||
}
|
||||
|
||||
// Push MGA AssistNow data to the module
|
||||
// Check for UBX-MGA-ACK responses if required (if mgaAck is YES or ENQUIRE)
|
||||
// Wait for maxWait millis after sending each packet (if mgaAck is NO)
|
||||
// Return how many MGA packets were pushed successfully
|
||||
uint16_t SFE_UBLOX_GNSS::pushAssistNowData(String dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
// Push MGA AssistNow data to the module.
|
||||
// Check for UBX-MGA-ACK responses if required (if mgaAck is YES or ENQUIRE).
|
||||
// Wait for maxWait millis after sending each packet (if mgaAck is NO).
|
||||
// Return how many MGA packets were pushed successfully.
|
||||
// If skipTime is true, any UBX-MGA-INI-TIME_UTC or UBX-MGA-INI-TIME_GNSS packets found in the data will be skipped,
|
||||
// allowing the user to override with their own time data with setUTCTimeAssistance.
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->println(F("pushAssistNowData: OK so far... (1)"));
|
||||
_debugSerial->flush();
|
||||
}
|
||||
return (pushAssistNowDataInternal(false, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(false, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(bool skipTime, const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(skipTime, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(skipTime, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowDataInternal(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
size_t dataPtr = 0; // Pointer into dataBytes
|
||||
uint16_t packetsProcessed = 0; // Keep count of how many packets have been processed
|
||||
size_t packetsProcessed = 0; // Keep count of how many packets have been processed
|
||||
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->println(F("pushAssistNowData: OK so far... (2)"));
|
||||
_debugSerial->flush();
|
||||
}
|
||||
|
||||
bool checkForAcks = (mgaAck == SFE_UBLOX_MGA_ASSIST_ACK_YES); // If mgaAck is YES, always check for Acks
|
||||
|
||||
@@ -3997,11 +4026,13 @@ uint16_t SFE_UBLOX_GNSS::pushAssistNowData(String dataBytes, size_t numDataBytes
|
||||
if (ackAiding == 1)
|
||||
checkForAcks = true;
|
||||
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: mgaAck is ENQUIRE. getAckAiding returned "));
|
||||
_debugSerial->println(ackAiding);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If checkForAcks is true, then we need to set up storage for the UBX-MGA-ACK-DATA0 messages
|
||||
@@ -4017,11 +4048,17 @@ uint16_t SFE_UBLOX_GNSS::pushAssistNowData(String dataBytes, size_t numDataBytes
|
||||
// Start by checking the validity of the packet being pointed to
|
||||
bool dataIsOK = true;
|
||||
|
||||
dataIsOK &= (dataBytes[dataPtr + 0] == UBX_SYNCH_1); // Check for 0xB5
|
||||
dataIsOK &= (dataBytes[dataPtr + 1] == UBX_SYNCH_2); // Check for 0x62
|
||||
dataIsOK &= (dataBytes[dataPtr + 2] == UBX_CLASS_MGA); // Check for class UBX-MGA
|
||||
dataIsOK &= (*(dataBytes + dataPtr + 0) == UBX_SYNCH_1); // Check for 0xB5
|
||||
dataIsOK &= (*(dataBytes + dataPtr + 1) == UBX_SYNCH_2); // Check for 0x62
|
||||
dataIsOK &= (*(dataBytes + dataPtr + 2) == UBX_CLASS_MGA); // Check for class UBX-MGA
|
||||
|
||||
size_t packetLength = ((size_t)dataBytes[dataPtr + 4]) | (((size_t)dataBytes[dataPtr + 5]) << 8); // Extract the length
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->println(F("pushAssistNowData: OK so far... (3)"));
|
||||
_debugSerial->flush();
|
||||
}
|
||||
|
||||
size_t packetLength = ((size_t)*(dataBytes + dataPtr + 4)) | (((size_t)*(dataBytes + dataPtr + 5)) << 8); // Extract the length
|
||||
|
||||
uint8_t checksumA = 0;
|
||||
uint8_t checksumB = 0;
|
||||
@@ -4030,26 +4067,41 @@ uint16_t SFE_UBLOX_GNSS::pushAssistNowData(String dataBytes, size_t numDataBytes
|
||||
// or we reach the end of the AssistNow data (payloadPtr == numDataBytes)
|
||||
for (size_t payloadPtr = dataPtr + ((size_t)2); (payloadPtr < (dataPtr + packetLength + ((size_t)6))) && (payloadPtr < numDataBytes); payloadPtr++)
|
||||
{
|
||||
checksumA += dataBytes[payloadPtr];
|
||||
checksumA += *(dataBytes + payloadPtr);
|
||||
checksumB += checksumA;
|
||||
}
|
||||
// Check the checksum bytes
|
||||
dataIsOK &= (checksumA == dataBytes[dataPtr + packetLength + ((size_t)6)]);
|
||||
dataIsOK &= (checksumB == dataBytes[dataPtr + packetLength + ((size_t)7)]);
|
||||
dataIsOK &= (checksumA == *(dataBytes + dataPtr + packetLength + ((size_t)6)));
|
||||
dataIsOK &= (checksumB == *(dataBytes + dataPtr + packetLength + ((size_t)7)));
|
||||
|
||||
dataIsOK &= ((dataPtr + packetLength + ((size_t)8)) <= numDataBytes); // Check we haven't overrun
|
||||
|
||||
// If the data is valid, push it
|
||||
if (dataIsOK)
|
||||
{
|
||||
pushRawData((uint8_t *)&dataBytes[dataPtr], packetLength + ((size_t)8)); // Push the data
|
||||
// Check if this is time assistance data which should be skipped
|
||||
if ((skipTime) && ((*(dataBytes + dataPtr + 3) == UBX_MGA_INI_TIME_UTC) || (*(dataBytes + dataPtr + 3) == UBX_MGA_INI_TIME_GNSS)))
|
||||
{
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: skipped INI_TIME ID 0x"));
|
||||
if (*(dataBytes + dataPtr + 3) < 0x10)
|
||||
_debugSerial->print(F("0"));
|
||||
_debugSerial->println(*(dataBytes + dataPtr + 3), HEX);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
pushRawData((uint8_t *)(dataBytes + dataPtr), packetLength + ((size_t)8)); // Push the data
|
||||
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: packet ID 0x"));
|
||||
if (dataBytes[dataPtr + 3] < 0x10)
|
||||
if (*(dataBytes + dataPtr + 3) < 0x10)
|
||||
_debugSerial->print(F("0"));
|
||||
_debugSerial->print(dataBytes[dataPtr + 3], HEX);
|
||||
_debugSerial->print(*(dataBytes + dataPtr + 3), HEX);
|
||||
_debugSerial->print(F(" length "));
|
||||
_debugSerial->println(packetLength);
|
||||
}
|
||||
@@ -4064,31 +4116,35 @@ uint16_t SFE_UBLOX_GNSS::pushAssistNowData(String dataBytes, size_t numDataBytes
|
||||
if (packetUBXMGAACK->head != packetUBXMGAACK->tail) // Does the MGA ACK ringbuffer contain any ACK's?
|
||||
{
|
||||
bool dataAckd = true; // Check if we've received the correct ACK
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgId == dataBytes[dataPtr + 3]); // Check if the message ID matches
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[0] == dataBytes[dataPtr + 6]); // Check if the first four data bytes match
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[1] == dataBytes[dataPtr + 7]);
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[2] == dataBytes[dataPtr + 8]);
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[3] == dataBytes[dataPtr + 9]);
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgId == *(dataBytes + dataPtr + 3)); // Check if the message ID matches
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[0] == *(dataBytes + dataPtr + 6)); // Check if the first four data bytes match
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[1] == *(dataBytes + dataPtr + 7));
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[2] == *(dataBytes + dataPtr + 8));
|
||||
dataAckd &= (packetUBXMGAACK->data[packetUBXMGAACK->tail].msgPayloadStart[3] == *(dataBytes + dataPtr + 9));
|
||||
|
||||
if (dataAckd) // Is this the ACK we are looking for?
|
||||
{
|
||||
if ((packetUBXMGAACK->data[packetUBXMGAACK->tail].type == (uint8_t)1) && (packetUBXMGAACK->data[packetUBXMGAACK->tail].infoCode == (uint8_t)SFE_UBLOX_MGA_ACK_INFOCODE_ACCEPTED))
|
||||
{
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: packet was accepted after "));
|
||||
_debugSerial->print(millis() - startTime);
|
||||
_debugSerial->println(F(" ms"));
|
||||
}
|
||||
#endif
|
||||
packetsProcessed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: packet was _not_ accepted. infoCode is "));
|
||||
_debugSerial->println(packetUBXMGAACK->data[packetUBXMGAACK->tail].infoCode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
keepGoing = false;
|
||||
}
|
||||
@@ -4116,30 +4172,36 @@ uint16_t SFE_UBLOX_GNSS::pushAssistNowData(String dataBytes, size_t numDataBytes
|
||||
delay(maxWait);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dataPtr += packetLength + ((size_t)8); // Point to the next message
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
// The data was invalid. Send a debug message and then try to find the next 0xB5
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: bad data - ignored! dataPtr is "));
|
||||
_debugSerial->println(dataPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((dataPtr < numDataBytes) && (dataBytes[++dataPtr] != UBX_SYNCH_1))
|
||||
while ((dataPtr < numDataBytes) && (*(dataBytes + ++dataPtr) != UBX_SYNCH_1))
|
||||
{
|
||||
; // Increment dataPtr until we are pointing at the next 0xB5 - or we reach the end of the data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: packetsProcessed: "));
|
||||
_debugSerial->println(packetsProcessed);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (packetsProcessed);
|
||||
}
|
||||
@@ -4159,6 +4221,50 @@ bool SFE_UBLOX_GNSS::initPacketUBXMGAACK()
|
||||
return (true);
|
||||
}
|
||||
|
||||
// Provide initial time assistance
|
||||
bool SFE_UBLOX_GNSS::setUTCTimeAssistance(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t nanos, uint16_t tAccS, uint32_t tAccNs, uint8_t source, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
uint8_t iniTimeUTC[32]; // Create the UBX-MGA-INI-TIME_UTC message by hand
|
||||
memset(iniTimeUTC, 0x00, 32); // Set all unused / reserved bytes and the checksum to zero
|
||||
|
||||
iniTimeUTC[0] = UBX_SYNCH_1; // Sync char 1
|
||||
iniTimeUTC[1] = UBX_SYNCH_2; // Sync char 2
|
||||
iniTimeUTC[2] = UBX_CLASS_MGA; // Class
|
||||
iniTimeUTC[3] = UBX_MGA_INI_TIME_UTC; // ID
|
||||
iniTimeUTC[4] = 24; // Length LSB
|
||||
iniTimeUTC[5] = 0x00; // Length MSB
|
||||
iniTimeUTC[6] = 0x10; // type
|
||||
iniTimeUTC[7] = 0x00; // version
|
||||
iniTimeUTC[8] = source; // ref (source)
|
||||
iniTimeUTC[9] = 0x80; // leapSecs. Set to 0x80 = unknown
|
||||
iniTimeUTC[10] = (uint8_t)(year & 0xFF); // year LSB
|
||||
iniTimeUTC[11] = (uint8_t)(year >> 8); // year MSB
|
||||
iniTimeUTC[12] = month; // month starting at 1
|
||||
iniTimeUTC[13] = day; // day starting at 1
|
||||
iniTimeUTC[14] = hour; // hour 0:23
|
||||
iniTimeUTC[15] = minute; // minute 0:59
|
||||
iniTimeUTC[16] = second; // seconds 0:59
|
||||
iniTimeUTC[18] = (uint8_t)(nanos & 0xFF); // nanoseconds LSB
|
||||
iniTimeUTC[19] = (uint8_t)((nanos >> 8) & 0xFF);
|
||||
iniTimeUTC[20] = (uint8_t)((nanos >> 16) & 0xFF);
|
||||
iniTimeUTC[21] = (uint8_t)(nanos >> 24); // nanoseconds MSB
|
||||
iniTimeUTC[22] = (uint8_t)(tAccS & 0xFF); // seconds part of the accuracy LSB
|
||||
iniTimeUTC[23] = (uint8_t)(tAccS >> 8); // seconds part of the accuracy MSB
|
||||
iniTimeUTC[26] = (uint8_t)(tAccNs & 0xFF); // nanoseconds part of the accuracy LSB
|
||||
iniTimeUTC[27] = (uint8_t)((tAccNs >> 8) & 0xFF);
|
||||
iniTimeUTC[28] = (uint8_t)((tAccNs >> 16) & 0xFF);
|
||||
iniTimeUTC[29] = (uint8_t)(tAccNs >> 24); // nanoseconds part of the accuracy MSB
|
||||
|
||||
for (uint8_t i = 2; i < 30; i++) // Calculate the checksum
|
||||
{
|
||||
iniTimeUTC[30] += iniTimeUTC[i];
|
||||
iniTimeUTC[31] += iniTimeUTC[30];
|
||||
}
|
||||
|
||||
// Return true if the one packet was pushed successfully
|
||||
return (pushAssistNowData(true, iniTimeUTC, 32, mgaAck, maxWait) == 1);
|
||||
}
|
||||
|
||||
// Support for data logging
|
||||
|
||||
//Set the file buffer size. This must be called _before_ .begin
|
||||
|
||||
@@ -704,12 +704,23 @@ public:
|
||||
// Default to using a restart between transmissions. But processors like ESP32 seem to need a stop (#30). Set stop to true to use a stop instead.
|
||||
bool pushRawData(uint8_t *dataBytes, size_t numDataBytes, bool stop = false);
|
||||
|
||||
// Push MGA AssistNow data to the module
|
||||
// Check for UBX-MGA-ACK responses if required (if mgaAck is YES or ENQUIRE)
|
||||
// Wait for maxWait millis after sending each packet (if mgaAck is NO)
|
||||
// Return how many MGA packets were pushed successfully
|
||||
// Push MGA AssistNow data to the module.
|
||||
// Check for UBX-MGA-ACK responses if required (if mgaAck is YES or ENQUIRE).
|
||||
// Wait for maxWait millis after sending each packet (if mgaAck is NO).
|
||||
// Return how many MGA packets were pushed successfully.
|
||||
// If skipTime is true, any UBX-MGA-INI-TIME_UTC or UBX-MGA-INI-TIME_GNSS packets found in the data will be skipped,
|
||||
// allowing the user to override with their own time data with setUTCTimeAssistance.
|
||||
#define defaultMGAdelay 7 // Default to waiting for 7ms between each MGA message
|
||||
uint16_t pushAssistNowData(String dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(bool skipTime, const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
|
||||
// Provide initial time assistance
|
||||
#define defaultMGAINITIMEtAccS 2 // Default to setting the seconds time accuracy to 2 seconds
|
||||
#define defaultMGAINITIMEtAccNs 0 // Default to setting the nanoseconds time accuracy to zero
|
||||
#define defaultMGAINITIMEsource 0 // Set default source to none, i.e. on receipt of message (will be inaccurate!)
|
||||
bool setUTCTimeAssistance(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t nanos = 0, uint16_t tAccS = defaultMGAINITIMEtAccS, uint32_t tAccNs = defaultMGAINITIMEtAccNs, uint8_t source = defaultMGAINITIMEsource, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
|
||||
// Support for data logging
|
||||
void setFileBufferSize(uint16_t bufferSize); // Set the size of the file buffer. This must be called _before_ .begin.
|
||||
@@ -1306,6 +1317,7 @@ private:
|
||||
//Functions
|
||||
bool checkUbloxInternal(ubxPacket *incomingUBX, uint8_t requestedClass = 255, uint8_t requestedID = 255); //Checks module with user selected commType
|
||||
void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B
|
||||
size_t pushAssistNowDataInternal(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
|
||||
//Return true if this "automatic" message has storage allocated for it
|
||||
bool checkAutomatic(uint8_t Class, uint8_t ID);
|
||||
|
||||
Reference in New Issue
Block a user