fix(mavlink): validate GPS UTC timestamps (#27507)

* fix(mavlink): validate GPS UTC timestamps

Handle unavailable GPS UTC time in OpenDroneID system and uAvionix
ADSB dynamic messages. Use the protocol-defined unknown values instead
of deriving invalid timestamps.

* Apply suggestion from @dakejahl

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>

* Apply suggestion from @dakejahl

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>

* Apply suggestion from @dakejahl

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>

---------

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
This commit is contained in:
Eurus
2026-06-02 13:25:59 +08:00
committed by GitHub
parent 4b015fbdeb
commit 4c4d5ed1d9
2 changed files with 18 additions and 4 deletions

View File

@@ -90,8 +90,13 @@ private:
msg.operator_altitude_geo = home_position.alt + wgs84_amsl_offset;
// timestamp: 32 bit Unix Timestamp in seconds since 00:00:00 01/01/2019.
static uint64_t utc_offset_s = 1'546'300'800; // UTC seconds since 00:00:00 01/01/2019
msg.timestamp = vehicle_gps_position.time_utc_usec / 1e6 - utc_offset_s;
// Timestamp not available is indicated by 0.
static constexpr uint64_t utc_offset_us = 1'546'300'800ULL * 1'000'000ULL;
if (vehicle_gps_position.time_utc_usec >= utc_offset_us) {
const uint64_t timestamp_s = (vehicle_gps_position.time_utc_usec - utc_offset_us) / 1'000'000ULL;
msg.timestamp = static_cast<uint32_t>(timestamp_s);
}
mavlink_msg_open_drone_id_system_send_struct(_mavlink->get_channel(), &msg);

View File

@@ -83,9 +83,18 @@ private:
vehicle_air_data_s vehicle_air_data;
_vehicle_air_data_sub.copy(&vehicle_air_data);
// UTC seconds since 00:00:00 01/06/1980 (GPS epoch). If unknown set to UINT32_MAX.
static constexpr uint64_t gps_epoch_offset_us = 315'964'800ULL * 1'000'000ULL;
uint32_t gps_epoch_time_s = UINT32_MAX;
if (vehicle_gps_position.time_utc_usec >= gps_epoch_offset_us) {
const uint64_t timestamp_s = (vehicle_gps_position.time_utc_usec - gps_epoch_offset_us) / 1'000'000ULL;
gps_epoch_time_s = static_cast<uint32_t>(timestamp_s);
}
// Required update for dynamic message is 5 [Hz]
mavlink_uavionix_adsb_out_dynamic_t dynamic_msg = {
.utcTime = static_cast<uint32_t>(vehicle_gps_position.time_utc_usec / 1000000ULL),
.utcTime = gps_epoch_time_s,
.gpsLat = static_cast<int32_t>(round(vehicle_gps_position.latitude_deg * 1e7)),
.gpsLon = static_cast<int32_t>(round(vehicle_gps_position.longitude_deg * 1e7)),
.gpsAlt = static_cast<int32_t>(round(vehicle_gps_position.altitude_ellipsoid_m * 1e3)), // convert [m] to [mm]
@@ -104,7 +113,7 @@ private:
};
if (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) {
dynamic_msg.state |= ~UAVIONIX_ADSB_OUT_DYNAMIC_STATE_ON_GROUND;
dynamic_msg.state &= ~UAVIONIX_ADSB_OUT_DYNAMIC_STATE_ON_GROUND;
}
mavlink_msg_uavionix_adsb_out_dynamic_send_struct(_mavlink->get_channel(), &dynamic_msg);