diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,5 +1,5 @@
 name:                  sbp
-version:               4.1.2
+version:               4.1.3
 synopsis:              SwiftNav's SBP Library
 homepage:              https://github.com/swift-nav/libsbp
 license:               MIT
diff --git a/src/SwiftNav/SBP/Msg.hs b/src/SwiftNav/SBP/Msg.hs
--- a/src/SwiftNav/SBP/Msg.hs
+++ b/src/SwiftNav/SBP/Msg.hs
@@ -196,6 +196,7 @@
    | SBPMsgResetDep MsgResetDep Msg
    | SBPMsgResetFilters MsgResetFilters Msg
    | SBPMsgSbasRaw MsgSbasRaw Msg
+   | SBPMsgSensorAidEvent MsgSensorAidEvent Msg
    | SBPMsgSetTime MsgSetTime Msg
    | SBPMsgSettingsReadByIndexDone MsgSettingsReadByIndexDone Msg
    | SBPMsgSettingsReadByIndexReq MsgSettingsReadByIndexReq Msg
@@ -412,6 +413,7 @@
           | _msgSBPType == msgResetDep = SBPMsgResetDep (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgResetFilters = SBPMsgResetFilters (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgSbasRaw = SBPMsgSbasRaw (decode (fromStrict (unBytes _msgSBPPayload))) m
+          | _msgSBPType == msgSensorAidEvent = SBPMsgSensorAidEvent (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgSetTime = SBPMsgSetTime (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgSettingsReadByIndexDone = SBPMsgSettingsReadByIndexDone (decode (fromStrict (unBytes _msgSBPPayload))) m
           | _msgSBPType == msgSettingsReadByIndexReq = SBPMsgSettingsReadByIndexReq (decode (fromStrict (unBytes _msgSBPPayload))) m
@@ -620,6 +622,7 @@
       encoder (SBPMsgResetDep _ m) = put m
       encoder (SBPMsgResetFilters _ m) = put m
       encoder (SBPMsgSbasRaw _ m) = put m
+      encoder (SBPMsgSensorAidEvent _ m) = put m
       encoder (SBPMsgSetTime _ m) = put m
       encoder (SBPMsgSettingsReadByIndexDone _ m) = put m
       encoder (SBPMsgSettingsReadByIndexReq _ m) = put m
@@ -832,6 +835,7 @@
         | msgType == msgResetDep = SBPMsgResetDep <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgResetFilters = SBPMsgResetFilters <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgSbasRaw = SBPMsgSbasRaw <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
+        | msgType == msgSensorAidEvent = SBPMsgSensorAidEvent <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgSetTime = SBPMsgSetTime <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgSettingsReadByIndexDone = SBPMsgSettingsReadByIndexDone <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
         | msgType == msgSettingsReadByIndexReq = SBPMsgSettingsReadByIndexReq <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj
@@ -1045,6 +1049,7 @@
   toJSON (SBPMsgResetDep _ m) = toJSON m
   toJSON (SBPMsgResetFilters n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgSbasRaw n m) = toJSON n <<>> toJSON m
+  toJSON (SBPMsgSensorAidEvent n m) = toJSON n <<>> toJSON m
   toJSON (SBPMsgSetTime _ m) = toJSON m
   toJSON (SBPMsgSettingsReadByIndexDone _ m) = toJSON m
   toJSON (SBPMsgSettingsReadByIndexReq n m) = toJSON n <<>> toJSON m
@@ -1252,6 +1257,7 @@
   msg f (SBPMsgResetDep n m) = SBPMsgResetDep n <$> f m
   msg f (SBPMsgResetFilters n m) = SBPMsgResetFilters n <$> f m
   msg f (SBPMsgSbasRaw n m) = SBPMsgSbasRaw n <$> f m
+  msg f (SBPMsgSensorAidEvent n m) = SBPMsgSensorAidEvent n <$> f m
   msg f (SBPMsgSetTime n m) = SBPMsgSetTime n <$> f m
   msg f (SBPMsgSettingsReadByIndexDone n m) = SBPMsgSettingsReadByIndexDone n <$> f m
   msg f (SBPMsgSettingsReadByIndexReq n m) = SBPMsgSettingsReadByIndexReq n <$> f m
diff --git a/src/SwiftNav/SBP/Navigation.hs b/src/SwiftNav/SBP/Navigation.hs
--- a/src/SwiftNav/SBP/Navigation.hs
+++ b/src/SwiftNav/SBP/Navigation.hs
@@ -1620,28 +1620,31 @@
 --
 -- This message reports the receiver course over ground (COG) and speed over
 -- ground (SOG) based on the horizontal (N-E) components of the NED velocity
--- vector. It also includes the vertical velocity in the form of the
--- D-component of the NED velocity vector. The NED coordinate system is
--- defined as the local WGS84 tangent  plane centered at the current position.
--- The full GPS time is given by the  preceding MSG_GPS_TIME with the matching
--- time-of-week (tow). Note: course over ground represents the receiver's
--- direction of travel,  but not necessarily the device heading.
+-- vector. It also includes the vertical velocity coordinate. A flag is
+-- provided to indicate whether the COG value has been frozen. When  the flag
+-- is set to true, the COG field is set to its last valid value until  the
+-- system exceeds a minimum velocity threshold. No other fields are  affected
+-- by this flag.  The NED coordinate system is defined as the local WGS84
+-- tangent  plane centered at the current position. The full GPS time is given
+-- by the  preceding MSG_GPS_TIME with the matching time-of-week (tow). Note:
+-- course over ground represents the receiver's direction of travel,  but not
+-- necessarily the device heading.
 data MsgVelCog = MsgVelCog
-  { _msgVelCog_tow          :: !Word32
+  { _msgVelCog_tow         :: !Word32
     -- ^ GPS Time of Week
-  , _msgVelCog_cog          :: !Word32
-    -- ^ Course over ground relative to local north
-  , _msgVelCog_sog          :: !Word32
-    -- ^ Speed over ground
-  , _msgVelCog_vel_d        :: !Int32
-    -- ^ Velocity Down coordinate
+  , _msgVelCog_cog         :: !Word32
+    -- ^ Course over ground relative to north direction
+  , _msgVelCog_sog         :: !Word32
+    -- ^ Speed over ground (based on horizontal velocity)
+  , _msgVelCog_v_up        :: !Int32
+    -- ^ Vertical velocity component (positive up)
   , _msgVelCog_cog_accuracy :: !Word32
     -- ^ Course over ground estimated standard deviation
   , _msgVelCog_sog_accuracy :: !Word32
     -- ^ Speed over ground estimated standard deviation
-  , _msgVelCog_vel_d_accuracy :: !Word32
+  , _msgVelCog_v_up_accuracy :: !Word32
     -- ^ Vertical velocity estimated standard deviation
-  , _msgVelCog_flags        :: !Word8
+  , _msgVelCog_flags       :: !Word16
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -1650,22 +1653,22 @@
     _msgVelCog_tow <- getWord32le
     _msgVelCog_cog <- getWord32le
     _msgVelCog_sog <- getWord32le
-    _msgVelCog_vel_d <- (fromIntegral <$> getWord32le)
+    _msgVelCog_v_up <- (fromIntegral <$> getWord32le)
     _msgVelCog_cog_accuracy <- getWord32le
     _msgVelCog_sog_accuracy <- getWord32le
-    _msgVelCog_vel_d_accuracy <- getWord32le
-    _msgVelCog_flags <- getWord8
+    _msgVelCog_v_up_accuracy <- getWord32le
+    _msgVelCog_flags <- getWord16le
     pure MsgVelCog {..}
 
   put MsgVelCog {..} = do
     putWord32le _msgVelCog_tow
     putWord32le _msgVelCog_cog
     putWord32le _msgVelCog_sog
-    (putWord32le . fromIntegral) _msgVelCog_vel_d
+    (putWord32le . fromIntegral) _msgVelCog_v_up
     putWord32le _msgVelCog_cog_accuracy
     putWord32le _msgVelCog_sog_accuracy
-    putWord32le _msgVelCog_vel_d_accuracy
-    putWord8 _msgVelCog_flags
+    putWord32le _msgVelCog_v_up_accuracy
+    putWord16le _msgVelCog_flags
 
 $(makeSBP 'msgVelCog ''MsgVelCog)
 $(makeJSON "_msgVelCog_" ''MsgVelCog)
diff --git a/src/SwiftNav/SBP/System.hs b/src/SwiftNav/SBP/System.hs
--- a/src/SwiftNav/SBP/System.hs
+++ b/src/SwiftNav/SBP/System.hs
@@ -417,6 +417,60 @@
 $(makeJSON "_msgPpsTime_" ''MsgPpsTime)
 $(makeLenses ''MsgPpsTime)
 
+msgSensorAidEvent :: Word16
+msgSensorAidEvent = 0xFF09
+
+-- | SBP class for message MSG_SENSOR_AID_EVENT (0xFF09).
+--
+-- This diagnostic message contains state and update status information for
+-- all sensors that are being used by the fusion engine. This message will be
+-- generated asynchronously to the solution messages and will be emitted
+-- anytime a sensor update is being processed.
+data MsgSensorAidEvent = MsgSensorAidEvent
+  { _msgSensorAidEvent_time           :: !Word32
+    -- ^ Update timestamp in milliseconds.
+  , _msgSensorAidEvent_sensor_type    :: !Word8
+    -- ^ Sensor type
+  , _msgSensorAidEvent_sensor_id      :: !Word16
+    -- ^ Sensor identifier
+  , _msgSensorAidEvent_sensor_state   :: !Word8
+    -- ^ Reserved for future use
+  , _msgSensorAidEvent_n_available_meas :: !Word8
+    -- ^ Number of available measurements in this epoch
+  , _msgSensorAidEvent_n_attempted_meas :: !Word8
+    -- ^ Number of attempted measurements in this epoch
+  , _msgSensorAidEvent_n_accepted_meas :: !Word8
+    -- ^ Number of accepted measurements in this epoch
+  , _msgSensorAidEvent_flags          :: !Word32
+    -- ^ Reserved for future use
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgSensorAidEvent where
+  get = do
+    _msgSensorAidEvent_time <- getWord32le
+    _msgSensorAidEvent_sensor_type <- getWord8
+    _msgSensorAidEvent_sensor_id <- getWord16le
+    _msgSensorAidEvent_sensor_state <- getWord8
+    _msgSensorAidEvent_n_available_meas <- getWord8
+    _msgSensorAidEvent_n_attempted_meas <- getWord8
+    _msgSensorAidEvent_n_accepted_meas <- getWord8
+    _msgSensorAidEvent_flags <- getWord32le
+    pure MsgSensorAidEvent {..}
+
+  put MsgSensorAidEvent {..} = do
+    putWord32le _msgSensorAidEvent_time
+    putWord8 _msgSensorAidEvent_sensor_type
+    putWord16le _msgSensorAidEvent_sensor_id
+    putWord8 _msgSensorAidEvent_sensor_state
+    putWord8 _msgSensorAidEvent_n_available_meas
+    putWord8 _msgSensorAidEvent_n_attempted_meas
+    putWord8 _msgSensorAidEvent_n_accepted_meas
+    putWord32le _msgSensorAidEvent_flags
+
+$(makeSBP 'msgSensorAidEvent ''MsgSensorAidEvent)
+$(makeJSON "_msgSensorAidEvent_" ''MsgSensorAidEvent)
+$(makeLenses ''MsgSensorAidEvent)
+
 msgGroupMeta :: Word16
 msgGroupMeta = 0xFF0A
 
