diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,5 +1,5 @@
 name:                  sbp
-version:               1.2.8
+version:               2.0.0
 synopsis:              SwiftNav's SBP Library
 homepage:              https://github.com/swift-nav/libsbp
 license:               LGPL-3
diff --git a/src/SwiftNav/SBP.hs b/src/SwiftNav/SBP.hs
--- a/src/SwiftNav/SBP.hs
+++ b/src/SwiftNav/SBP.hs
@@ -58,12 +58,16 @@
    | SBPMsgAcqResultDepA MsgAcqResultDepA Msg
    | SBPMsgAcqResultDepB MsgAcqResultDepB Msg
    | SBPMsgAcqSvProfile MsgAcqSvProfile Msg
+   | SBPMsgAgeCorrections MsgAgeCorrections Msg
    | SBPMsgAlmanac MsgAlmanac Msg
    | SBPMsgBasePosEcef MsgBasePosEcef Msg
    | SBPMsgBasePosLlh MsgBasePosLlh Msg
    | SBPMsgBaselineEcef MsgBaselineEcef Msg
+   | SBPMsgBaselineEcefDepA MsgBaselineEcefDepA Msg
    | SBPMsgBaselineHeading MsgBaselineHeading Msg
+   | SBPMsgBaselineHeadingDepA MsgBaselineHeadingDepA Msg
    | SBPMsgBaselineNed MsgBaselineNed Msg
+   | SBPMsgBaselineNedDepA MsgBaselineNedDepA Msg
    | SBPMsgBootloaderHandshakeDepA MsgBootloaderHandshakeDepA Msg
    | SBPMsgBootloaderHandshakeReq MsgBootloaderHandshakeReq Msg
    | SBPMsgBootloaderHandshakeResp MsgBootloaderHandshakeResp Msg
@@ -71,7 +75,9 @@
    | SBPMsgCwResults MsgCwResults Msg
    | SBPMsgCwStart MsgCwStart Msg
    | SBPMsgDeviceMonitor MsgDeviceMonitor Msg
+   | SBPMsgDgnssStatus MsgDgnssStatus Msg
    | SBPMsgDops MsgDops Msg
+   | SBPMsgDopsDepA MsgDopsDepA Msg
    | SBPMsgEphemerisDepA MsgEphemerisDepA Msg
    | SBPMsgEphemerisDepB MsgEphemerisDepB Msg
    | SBPMsgEphemerisDepC MsgEphemerisDepC Msg
@@ -92,7 +98,9 @@
    | SBPMsgFlashProgram MsgFlashProgram Msg
    | SBPMsgFlashReadReq MsgFlashReadReq Msg
    | SBPMsgFlashReadResp MsgFlashReadResp Msg
+   | SBPMsgFwd MsgFwd Msg
    | SBPMsgGpsTime MsgGpsTime Msg
+   | SBPMsgGpsTimeDepA MsgGpsTimeDepA Msg
    | SBPMsgGroupDelay MsgGroupDelay Msg
    | SBPMsgHeartbeat MsgHeartbeat Msg
    | SBPMsgIarState MsgIarState Msg
@@ -106,8 +114,11 @@
    | SBPMsgObs MsgObs Msg
    | SBPMsgObsDepA MsgObsDepA Msg
    | SBPMsgObsDepB MsgObsDepB Msg
+   | SBPMsgObsDepC MsgObsDepC Msg
    | SBPMsgPosEcef MsgPosEcef Msg
+   | SBPMsgPosEcefDepA MsgPosEcefDepA Msg
    | SBPMsgPosLlh MsgPosLlh Msg
+   | SBPMsgPosLlhDepA MsgPosLlhDepA Msg
    | SBPMsgPrintDep MsgPrintDep Msg
    | SBPMsgReset MsgReset Msg
    | SBPMsgResetFilters MsgResetFilters Msg
@@ -135,8 +146,11 @@
    | SBPMsgUartState MsgUartState Msg
    | SBPMsgUartStateDepa MsgUartStateDepa Msg
    | SBPMsgUserData MsgUserData Msg
+   | SBPMsgUtcTime MsgUtcTime Msg
    | SBPMsgVelEcef MsgVelEcef Msg
+   | SBPMsgVelEcefDepA MsgVelEcefDepA Msg
    | SBPMsgVelNed MsgVelNed Msg
+   | SBPMsgVelNedDepA MsgVelNedDepA Msg
    | SBPMsgBadCrc Msg
    | SBPMsgUnknown Msg
   deriving ( Show, Read, Eq )
@@ -154,12 +168,16 @@
           | _msgSBPType == msgAcqResultDepA = SBPMsgAcqResultDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgAcqResultDepB = SBPMsgAcqResultDepB (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgAcqSvProfile = SBPMsgAcqSvProfile (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgAgeCorrections = SBPMsgAgeCorrections (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgAlmanac = SBPMsgAlmanac (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBasePosEcef = SBPMsgBasePosEcef (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBasePosLlh = SBPMsgBasePosLlh (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBaselineEcef = SBPMsgBaselineEcef (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgBaselineEcefDepA = SBPMsgBaselineEcefDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBaselineHeading = SBPMsgBaselineHeading (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgBaselineHeadingDepA = SBPMsgBaselineHeadingDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBaselineNed = SBPMsgBaselineNed (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgBaselineNedDepA = SBPMsgBaselineNedDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBootloaderHandshakeDepA = SBPMsgBootloaderHandshakeDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBootloaderHandshakeReq = SBPMsgBootloaderHandshakeReq (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgBootloaderHandshakeResp = SBPMsgBootloaderHandshakeResp (decode (fromStrict _msgSBPPayload)) m
@@ -167,7 +185,9 @@
           | _msgSBPType == msgCwResults = SBPMsgCwResults (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgCwStart = SBPMsgCwStart (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgDeviceMonitor = SBPMsgDeviceMonitor (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgDgnssStatus = SBPMsgDgnssStatus (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgDops = SBPMsgDops (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgDopsDepA = SBPMsgDopsDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgEphemerisDepA = SBPMsgEphemerisDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgEphemerisDepB = SBPMsgEphemerisDepB (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgEphemerisDepC = SBPMsgEphemerisDepC (decode (fromStrict _msgSBPPayload)) m
@@ -188,7 +208,9 @@
           | _msgSBPType == msgFlashProgram = SBPMsgFlashProgram (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgFlashReadReq = SBPMsgFlashReadReq (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgFlashReadResp = SBPMsgFlashReadResp (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgFwd = SBPMsgFwd (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgGpsTime = SBPMsgGpsTime (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgGpsTimeDepA = SBPMsgGpsTimeDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgGroupDelay = SBPMsgGroupDelay (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgHeartbeat = SBPMsgHeartbeat (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgIarState = SBPMsgIarState (decode (fromStrict _msgSBPPayload)) m
@@ -202,8 +224,11 @@
           | _msgSBPType == msgObs = SBPMsgObs (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgObsDepA = SBPMsgObsDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgObsDepB = SBPMsgObsDepB (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgObsDepC = SBPMsgObsDepC (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgPosEcef = SBPMsgPosEcef (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgPosEcefDepA = SBPMsgPosEcefDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgPosLlh = SBPMsgPosLlh (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgPosLlhDepA = SBPMsgPosLlhDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgPrintDep = SBPMsgPrintDep (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgReset = SBPMsgReset (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgResetFilters = SBPMsgResetFilters (decode (fromStrict _msgSBPPayload)) m
@@ -231,8 +256,11 @@
           | _msgSBPType == msgUartState = SBPMsgUartState (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgUartStateDepa = SBPMsgUartStateDepa (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgUserData = SBPMsgUserData (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgUtcTime = SBPMsgUtcTime (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgVelEcef = SBPMsgVelEcef (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgVelEcefDepA = SBPMsgVelEcefDepA (decode (fromStrict _msgSBPPayload)) m
           | _msgSBPType == msgVelNed = SBPMsgVelNed (decode (fromStrict _msgSBPPayload)) m
+          | _msgSBPType == msgVelNedDepA = SBPMsgVelNedDepA (decode (fromStrict _msgSBPPayload)) m
           | otherwise = SBPMsgUnknown m
 
   put sm = do
@@ -242,12 +270,16 @@
       encode' (SBPMsgAcqResultDepA _ m) = put m
       encode' (SBPMsgAcqResultDepB _ m) = put m
       encode' (SBPMsgAcqSvProfile _ m) = put m
+      encode' (SBPMsgAgeCorrections _ m) = put m
       encode' (SBPMsgAlmanac _ m) = put m
       encode' (SBPMsgBasePosEcef _ m) = put m
       encode' (SBPMsgBasePosLlh _ m) = put m
       encode' (SBPMsgBaselineEcef _ m) = put m
+      encode' (SBPMsgBaselineEcefDepA _ m) = put m
       encode' (SBPMsgBaselineHeading _ m) = put m
+      encode' (SBPMsgBaselineHeadingDepA _ m) = put m
       encode' (SBPMsgBaselineNed _ m) = put m
+      encode' (SBPMsgBaselineNedDepA _ m) = put m
       encode' (SBPMsgBootloaderHandshakeDepA _ m) = put m
       encode' (SBPMsgBootloaderHandshakeReq _ m) = put m
       encode' (SBPMsgBootloaderHandshakeResp _ m) = put m
@@ -255,7 +287,9 @@
       encode' (SBPMsgCwResults _ m) = put m
       encode' (SBPMsgCwStart _ m) = put m
       encode' (SBPMsgDeviceMonitor _ m) = put m
+      encode' (SBPMsgDgnssStatus _ m) = put m
       encode' (SBPMsgDops _ m) = put m
+      encode' (SBPMsgDopsDepA _ m) = put m
       encode' (SBPMsgEphemerisDepA _ m) = put m
       encode' (SBPMsgEphemerisDepB _ m) = put m
       encode' (SBPMsgEphemerisDepC _ m) = put m
@@ -276,7 +310,9 @@
       encode' (SBPMsgFlashProgram _ m) = put m
       encode' (SBPMsgFlashReadReq _ m) = put m
       encode' (SBPMsgFlashReadResp _ m) = put m
+      encode' (SBPMsgFwd _ m) = put m
       encode' (SBPMsgGpsTime _ m) = put m
+      encode' (SBPMsgGpsTimeDepA _ m) = put m
       encode' (SBPMsgGroupDelay _ m) = put m
       encode' (SBPMsgHeartbeat _ m) = put m
       encode' (SBPMsgIarState _ m) = put m
@@ -290,8 +326,11 @@
       encode' (SBPMsgObs _ m) = put m
       encode' (SBPMsgObsDepA _ m) = put m
       encode' (SBPMsgObsDepB _ m) = put m
+      encode' (SBPMsgObsDepC _ m) = put m
       encode' (SBPMsgPosEcef _ m) = put m
+      encode' (SBPMsgPosEcefDepA _ m) = put m
       encode' (SBPMsgPosLlh _ m) = put m
+      encode' (SBPMsgPosLlhDepA _ m) = put m
       encode' (SBPMsgPrintDep _ m) = put m
       encode' (SBPMsgReset _ m) = put m
       encode' (SBPMsgResetFilters _ m) = put m
@@ -319,8 +358,11 @@
       encode' (SBPMsgUartState _ m) = put m
       encode' (SBPMsgUartStateDepa _ m) = put m
       encode' (SBPMsgUserData _ m) = put m
+      encode' (SBPMsgUtcTime _ m) = put m
       encode' (SBPMsgVelEcef _ m) = put m
+      encode' (SBPMsgVelEcefDepA _ m) = put m
       encode' (SBPMsgVelNed _ m) = put m
+      encode' (SBPMsgVelNedDepA _ m) = put m
       encode' (SBPMsgUnknown m) = put m
       encode' (SBPMsgBadCrc m) = put m
 
@@ -333,12 +375,16 @@
         | msgType == msgAcqResultDepA = SBPMsgAcqResultDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgAcqResultDepB = SBPMsgAcqResultDepB <$> parseJSON obj <*> parseJSON obj
         | msgType == msgAcqSvProfile = SBPMsgAcqSvProfile <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgAgeCorrections = SBPMsgAgeCorrections <$> parseJSON obj <*> parseJSON obj
         | msgType == msgAlmanac = SBPMsgAlmanac <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBasePosEcef = SBPMsgBasePosEcef <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBasePosLlh = SBPMsgBasePosLlh <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBaselineEcef = SBPMsgBaselineEcef <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgBaselineEcefDepA = SBPMsgBaselineEcefDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBaselineHeading = SBPMsgBaselineHeading <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgBaselineHeadingDepA = SBPMsgBaselineHeadingDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBaselineNed = SBPMsgBaselineNed <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgBaselineNedDepA = SBPMsgBaselineNedDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBootloaderHandshakeDepA = SBPMsgBootloaderHandshakeDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBootloaderHandshakeReq = SBPMsgBootloaderHandshakeReq <$> parseJSON obj <*> parseJSON obj
         | msgType == msgBootloaderHandshakeResp = SBPMsgBootloaderHandshakeResp <$> parseJSON obj <*> parseJSON obj
@@ -346,7 +392,9 @@
         | msgType == msgCwResults = SBPMsgCwResults <$> parseJSON obj <*> parseJSON obj
         | msgType == msgCwStart = SBPMsgCwStart <$> parseJSON obj <*> parseJSON obj
         | msgType == msgDeviceMonitor = SBPMsgDeviceMonitor <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgDgnssStatus = SBPMsgDgnssStatus <$> parseJSON obj <*> parseJSON obj
         | msgType == msgDops = SBPMsgDops <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgDopsDepA = SBPMsgDopsDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgEphemerisDepA = SBPMsgEphemerisDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgEphemerisDepB = SBPMsgEphemerisDepB <$> parseJSON obj <*> parseJSON obj
         | msgType == msgEphemerisDepC = SBPMsgEphemerisDepC <$> parseJSON obj <*> parseJSON obj
@@ -367,7 +415,9 @@
         | msgType == msgFlashProgram = SBPMsgFlashProgram <$> parseJSON obj <*> parseJSON obj
         | msgType == msgFlashReadReq = SBPMsgFlashReadReq <$> parseJSON obj <*> parseJSON obj
         | msgType == msgFlashReadResp = SBPMsgFlashReadResp <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgFwd = SBPMsgFwd <$> parseJSON obj <*> parseJSON obj
         | msgType == msgGpsTime = SBPMsgGpsTime <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgGpsTimeDepA = SBPMsgGpsTimeDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgGroupDelay = SBPMsgGroupDelay <$> parseJSON obj <*> parseJSON obj
         | msgType == msgHeartbeat = SBPMsgHeartbeat <$> parseJSON obj <*> parseJSON obj
         | msgType == msgIarState = SBPMsgIarState <$> parseJSON obj <*> parseJSON obj
@@ -381,8 +431,11 @@
         | msgType == msgObs = SBPMsgObs <$> parseJSON obj <*> parseJSON obj
         | msgType == msgObsDepA = SBPMsgObsDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgObsDepB = SBPMsgObsDepB <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgObsDepC = SBPMsgObsDepC <$> parseJSON obj <*> parseJSON obj
         | msgType == msgPosEcef = SBPMsgPosEcef <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgPosEcefDepA = SBPMsgPosEcefDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgPosLlh = SBPMsgPosLlh <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgPosLlhDepA = SBPMsgPosLlhDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgPrintDep = SBPMsgPrintDep <$> parseJSON obj <*> parseJSON obj
         | msgType == msgReset = SBPMsgReset <$> parseJSON obj <*> parseJSON obj
         | msgType == msgResetFilters = SBPMsgResetFilters <$> parseJSON obj <*> parseJSON obj
@@ -410,8 +463,11 @@
         | msgType == msgUartState = SBPMsgUartState <$> parseJSON obj <*> parseJSON obj
         | msgType == msgUartStateDepa = SBPMsgUartStateDepa <$> parseJSON obj <*> parseJSON obj
         | msgType == msgUserData = SBPMsgUserData <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgUtcTime = SBPMsgUtcTime <$> parseJSON obj <*> parseJSON obj
         | msgType == msgVelEcef = SBPMsgVelEcef <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgVelEcefDepA = SBPMsgVelEcefDepA <$> parseJSON obj <*> parseJSON obj
         | msgType == msgVelNed = SBPMsgVelNed <$> parseJSON obj <*> parseJSON obj
+        | msgType == msgVelNedDepA = SBPMsgVelNedDepA <$> parseJSON obj <*> parseJSON obj
         | otherwise = SBPMsgUnknown <$> parseJSON obj
   parseJSON _ = mzero
 
@@ -426,12 +482,16 @@
   toJSON (SBPMsgAcqResultDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgAcqResultDepB n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgAcqSvProfile n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgAgeCorrections n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgAlmanac n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBasePosEcef n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBasePosLlh n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBaselineEcef n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgBaselineEcefDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBaselineHeading n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgBaselineHeadingDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBaselineNed n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgBaselineNedDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBootloaderHandshakeDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBootloaderHandshakeReq n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBootloaderHandshakeResp n m) = toJSON n `mergeValues` toJSON m
@@ -439,7 +499,9 @@
   toJSON (SBPMsgCwResults n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgCwStart n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgDeviceMonitor n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgDgnssStatus n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgDops n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgDopsDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgEphemerisDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgEphemerisDepB n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgEphemerisDepC n m) = toJSON n `mergeValues` toJSON m
@@ -460,7 +522,9 @@
   toJSON (SBPMsgFlashProgram n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgFlashReadReq n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgFlashReadResp n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgFwd n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgGpsTime n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgGpsTimeDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgGroupDelay n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgHeartbeat n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgIarState n m) = toJSON n `mergeValues` toJSON m
@@ -474,8 +538,11 @@
   toJSON (SBPMsgObs n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgObsDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgObsDepB n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgObsDepC n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgPosEcef n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgPosEcefDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgPosLlh n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgPosLlhDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgPrintDep n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgReset n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgResetFilters n m) = toJSON n `mergeValues` toJSON m
@@ -503,8 +570,11 @@
   toJSON (SBPMsgUartState n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgUartStateDepa n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgUserData n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgUtcTime n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgVelEcef n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgVelEcefDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgVelNed n m) = toJSON n `mergeValues` toJSON m
+  toJSON (SBPMsgVelNedDepA n m) = toJSON n `mergeValues` toJSON m
   toJSON (SBPMsgBadCrc m) = toJSON m
   toJSON (SBPMsgUnknown m) = toJSON m
 
@@ -513,12 +583,16 @@
   msg f (SBPMsgAcqResultDepA n m) = SBPMsgAcqResultDepA n <$> f m
   msg f (SBPMsgAcqResultDepB n m) = SBPMsgAcqResultDepB n <$> f m
   msg f (SBPMsgAcqSvProfile n m) = SBPMsgAcqSvProfile n <$> f m
+  msg f (SBPMsgAgeCorrections n m) = SBPMsgAgeCorrections n <$> f m
   msg f (SBPMsgAlmanac n m) = SBPMsgAlmanac n <$> f m
   msg f (SBPMsgBasePosEcef n m) = SBPMsgBasePosEcef n <$> f m
   msg f (SBPMsgBasePosLlh n m) = SBPMsgBasePosLlh n <$> f m
   msg f (SBPMsgBaselineEcef n m) = SBPMsgBaselineEcef n <$> f m
+  msg f (SBPMsgBaselineEcefDepA n m) = SBPMsgBaselineEcefDepA n <$> f m
   msg f (SBPMsgBaselineHeading n m) = SBPMsgBaselineHeading n <$> f m
+  msg f (SBPMsgBaselineHeadingDepA n m) = SBPMsgBaselineHeadingDepA n <$> f m
   msg f (SBPMsgBaselineNed n m) = SBPMsgBaselineNed n <$> f m
+  msg f (SBPMsgBaselineNedDepA n m) = SBPMsgBaselineNedDepA n <$> f m
   msg f (SBPMsgBootloaderHandshakeDepA n m) = SBPMsgBootloaderHandshakeDepA n <$> f m
   msg f (SBPMsgBootloaderHandshakeReq n m) = SBPMsgBootloaderHandshakeReq n <$> f m
   msg f (SBPMsgBootloaderHandshakeResp n m) = SBPMsgBootloaderHandshakeResp n <$> f m
@@ -526,7 +600,9 @@
   msg f (SBPMsgCwResults n m) = SBPMsgCwResults n <$> f m
   msg f (SBPMsgCwStart n m) = SBPMsgCwStart n <$> f m
   msg f (SBPMsgDeviceMonitor n m) = SBPMsgDeviceMonitor n <$> f m
+  msg f (SBPMsgDgnssStatus n m) = SBPMsgDgnssStatus n <$> f m
   msg f (SBPMsgDops n m) = SBPMsgDops n <$> f m
+  msg f (SBPMsgDopsDepA n m) = SBPMsgDopsDepA n <$> f m
   msg f (SBPMsgEphemerisDepA n m) = SBPMsgEphemerisDepA n <$> f m
   msg f (SBPMsgEphemerisDepB n m) = SBPMsgEphemerisDepB n <$> f m
   msg f (SBPMsgEphemerisDepC n m) = SBPMsgEphemerisDepC n <$> f m
@@ -547,7 +623,9 @@
   msg f (SBPMsgFlashProgram n m) = SBPMsgFlashProgram n <$> f m
   msg f (SBPMsgFlashReadReq n m) = SBPMsgFlashReadReq n <$> f m
   msg f (SBPMsgFlashReadResp n m) = SBPMsgFlashReadResp n <$> f m
+  msg f (SBPMsgFwd n m) = SBPMsgFwd n <$> f m
   msg f (SBPMsgGpsTime n m) = SBPMsgGpsTime n <$> f m
+  msg f (SBPMsgGpsTimeDepA n m) = SBPMsgGpsTimeDepA n <$> f m
   msg f (SBPMsgGroupDelay n m) = SBPMsgGroupDelay n <$> f m
   msg f (SBPMsgHeartbeat n m) = SBPMsgHeartbeat n <$> f m
   msg f (SBPMsgIarState n m) = SBPMsgIarState n <$> f m
@@ -561,8 +639,11 @@
   msg f (SBPMsgObs n m) = SBPMsgObs n <$> f m
   msg f (SBPMsgObsDepA n m) = SBPMsgObsDepA n <$> f m
   msg f (SBPMsgObsDepB n m) = SBPMsgObsDepB n <$> f m
+  msg f (SBPMsgObsDepC n m) = SBPMsgObsDepC n <$> f m
   msg f (SBPMsgPosEcef n m) = SBPMsgPosEcef n <$> f m
+  msg f (SBPMsgPosEcefDepA n m) = SBPMsgPosEcefDepA n <$> f m
   msg f (SBPMsgPosLlh n m) = SBPMsgPosLlh n <$> f m
+  msg f (SBPMsgPosLlhDepA n m) = SBPMsgPosLlhDepA n <$> f m
   msg f (SBPMsgPrintDep n m) = SBPMsgPrintDep n <$> f m
   msg f (SBPMsgReset n m) = SBPMsgReset n <$> f m
   msg f (SBPMsgResetFilters n m) = SBPMsgResetFilters n <$> f m
@@ -590,7 +671,10 @@
   msg f (SBPMsgUartState n m) = SBPMsgUartState n <$> f m
   msg f (SBPMsgUartStateDepa n m) = SBPMsgUartStateDepa n <$> f m
   msg f (SBPMsgUserData n m) = SBPMsgUserData n <$> f m
+  msg f (SBPMsgUtcTime n m) = SBPMsgUtcTime n <$> f m
   msg f (SBPMsgVelEcef n m) = SBPMsgVelEcef n <$> f m
+  msg f (SBPMsgVelEcefDepA n m) = SBPMsgVelEcefDepA n <$> f m
   msg f (SBPMsgVelNed n m) = SBPMsgVelNed n <$> f m
+  msg f (SBPMsgVelNedDepA n m) = SBPMsgVelNedDepA n <$> f m
   msg f (SBPMsgUnknown m) = SBPMsgUnknown <$> f m
   msg f (SBPMsgBadCrc m) = SBPMsgBadCrc <$> f m
diff --git a/src/SwiftNav/SBP/Bootload.hs b/src/SwiftNav/SBP/Bootload.hs
--- a/src/SwiftNav/SBP/Bootload.hs
+++ b/src/SwiftNav/SBP/Bootload.hs
@@ -7,9 +7,9 @@
 -- Stability:   experimental
 -- Portability: portable
 --
--- Messages for the bootloading configuration on the device.  Note that some of
--- these messages share the same message type ID for both the host request and
--- the device response.
+-- Messages for the bootloading configuration of a Piksi 2.3.1.  This message
+-- group does not apply to Piksi Multi.  Note that some of these messages share
+-- the same message type ID for both the host request and the device response.
 
 module SwiftNav.SBP.Bootload where
 
diff --git a/src/SwiftNav/SBP/Flash.hs b/src/SwiftNav/SBP/Flash.hs
--- a/src/SwiftNav/SBP/Flash.hs
+++ b/src/SwiftNav/SBP/Flash.hs
@@ -9,7 +9,8 @@
 --
 -- Messages for reading/writing the device's onboard flash memory. Many of
 -- these messages target specific flash memory peripherals used in Swift
--- Navigation devices: the STM32 flash and the M25Pxx FPGA configuration flash.
+-- Navigation devices: the STM32 flash and the M25Pxx FPGA configuration flash
+-- from Piksi 2.3.1.  This module does not apply  to Piksi Multi.
 
 module SwiftNav.SBP.Flash where
 
diff --git a/src/SwiftNav/SBP/Gnss.hs b/src/SwiftNav/SBP/Gnss.hs
--- a/src/SwiftNav/SBP/Gnss.hs
+++ b/src/SwiftNav/SBP/Gnss.hs
@@ -27,6 +27,31 @@
 import SwiftNav.SBP.TH
 import SwiftNav.SBP.Types
 
+-- | GnssSignal16.
+--
+-- Signal identifier containing constellation, band, and satellite identifier
+-- - 0 GPS L1CA        - 1 GPS L2CM        - 2 SBAS L1CA        - 3 GLO L1CA
+-- - 4 GLO L2CA        - 5 GPS L1P        - 6 GPS L2P
+data GnssSignal16 = GnssSignal16
+  { _gnssSignal16_sat :: Word8
+    -- ^ Constellation-specific satellite identifier
+  , _gnssSignal16_code :: Word8
+    -- ^ Signal constellation, band and code
+  } deriving ( Show, Read, Eq )
+
+instance Binary GnssSignal16 where
+  get = do
+    _gnssSignal16_sat <- getWord8
+    _gnssSignal16_code <- getWord8
+    return GnssSignal16 {..}
+
+  put GnssSignal16 {..} = do
+    putWord8 _gnssSignal16_sat
+    putWord8 _gnssSignal16_code
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_gnssSignal16_" . stripPrefix "_gnssSignal16_"}
+             ''GnssSignal16)
+$(makeLenses ''GnssSignal16)
+
 -- | GnssSignal.
 --
 -- Signal identifier containing constellation, band, and satellite identifier
@@ -77,6 +102,38 @@
 $(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_gpsTime_" . stripPrefix "_gpsTime_"}
              ''GpsTime)
 $(makeLenses ''GpsTime)
+
+-- | GPSTimeNano.
+--
+-- A wire-appropriate GPS time, defined as the number of milliseconds since
+-- beginning of the week on the Saturday/Sunday A wire-appropriate receiver
+-- clock time, defined as the time since the beginning of the week on the
+-- Saturday/Sunday transition. In most cases, observations are epoch aligned
+-- so ns field will be 0.
+data GpsTimeNano = GpsTimeNano
+  { _gpsTimeNano_tow :: Word32
+    -- ^ Milliseconds since start of GPS week
+  , _gpsTimeNano_ns :: Int32
+    -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
+    -- 500000)
+  , _gpsTimeNano_wn :: Word16
+    -- ^ GPS week number
+  } deriving ( Show, Read, Eq )
+
+instance Binary GpsTimeNano where
+  get = do
+    _gpsTimeNano_tow <- getWord32le
+    _gpsTimeNano_ns <- fromIntegral <$> getWord32le
+    _gpsTimeNano_wn <- getWord16le
+    return GpsTimeNano {..}
+
+  put GpsTimeNano {..} = do
+    putWord32le _gpsTimeNano_tow
+    putWord32le $ fromIntegral _gpsTimeNano_ns
+    putWord16le _gpsTimeNano_wn
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_gpsTimeNano_" . stripPrefix "_gpsTimeNano_"}
+             ''GpsTimeNano)
+$(makeLenses ''GpsTimeNano)
 
 -- | CarrierPhase.
 --
diff --git a/src/SwiftNav/SBP/Logging.hs b/src/SwiftNav/SBP/Logging.hs
--- a/src/SwiftNav/SBP/Logging.hs
+++ b/src/SwiftNav/SBP/Logging.hs
@@ -58,6 +58,45 @@
              ''MsgLog)
 $(makeLenses ''MsgLog)
 
+msgFwd :: Word16
+msgFwd = 0x0402
+
+-- | SBP class for message MSG_FWD (0x0402).
+--
+-- This message provides the ability to forward messages over SBP.  This may
+-- take the form of wrapping up SBP messages received by Piksi for logging
+-- purposes or wrapping  another protocol with SBP.  The source identifier
+-- indicates from what interface a forwarded stream derived. The protocol
+-- identifier identifies what the expected protocol the forwarded msg contains.
+-- Protocol 0 represents SBP and the remaining values are implementation
+-- defined.
+data MsgFwd = MsgFwd
+  { _msgFwd_source    :: Word8
+    -- ^ source identifier
+  , _msgFwd_protocol  :: Word8
+    -- ^ protocol identifier
+  , _msgFwd_fwd_payload :: Text
+    -- ^ variable length wrapped binary message
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgFwd where
+  get = do
+    _msgFwd_source <- getWord8
+    _msgFwd_protocol <- getWord8
+    _msgFwd_fwd_payload <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
+    return MsgFwd {..}
+
+  put MsgFwd {..} = do
+    putWord8 _msgFwd_source
+    putWord8 _msgFwd_protocol
+    putByteString $ encodeUtf8 _msgFwd_fwd_payload
+
+$(deriveSBP 'msgFwd ''MsgFwd)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgFwd_" . stripPrefix "_msgFwd_"}
+             ''MsgFwd)
+$(makeLenses ''MsgFwd)
+
 msgTweet :: Word16
 msgTweet = 0x0012
 
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
@@ -36,9 +36,9 @@
 import SwiftNav.SBP.Types
 
 msgGpsTime :: Word16
-msgGpsTime = 0x0100
+msgGpsTime = 0x0102
 
--- | SBP class for message MSG_GPS_TIME (0x0100).
+-- | SBP class for message MSG_GPS_TIME (0x0102).
 --
 -- This message reports the GPS time, representing the time since the GPS epoch
 -- began on midnight January 6, 1980 UTC. GPS time counts the weeks and seconds
@@ -81,13 +81,75 @@
              ''MsgGpsTime)
 $(makeLenses ''MsgGpsTime)
 
+msgUtcTime :: Word16
+msgUtcTime = 0x0103
+
+-- | SBP class for message MSG_UTC_TIME (0x0103).
+--
+-- This message reports the Universal Coordinated Time (UTC).  Note the flags
+-- which indicate the source of the UTC offset value and source of the time
+-- fix.
+data MsgUtcTime = MsgUtcTime
+  { _msgUtcTime_flags :: Word8
+    -- ^ Indicates source and time validity
+  , _msgUtcTime_tow   :: Word32
+    -- ^ GPS time of week rounded to the nearest millisecond
+  , _msgUtcTime_year  :: Word16
+    -- ^ Year
+  , _msgUtcTime_month :: Word8
+    -- ^ Month (range 1 .. 12)
+  , _msgUtcTime_day   :: Word8
+    -- ^ days in the month (range 1-31)
+  , _msgUtcTime_hours :: Word8
+    -- ^ hours of day (range 0-23)
+  , _msgUtcTime_minutes :: Word8
+    -- ^ minutes of hour (range 0-59)
+  , _msgUtcTime_seconds :: Word8
+    -- ^ seconds of minute (range 0-60)
+  , _msgUtcTime_ns    :: Int32
+    -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
+    -- 500000)
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgUtcTime where
+  get = do
+    _msgUtcTime_flags <- getWord8
+    _msgUtcTime_tow <- getWord32le
+    _msgUtcTime_year <- getWord16le
+    _msgUtcTime_month <- getWord8
+    _msgUtcTime_day <- getWord8
+    _msgUtcTime_hours <- getWord8
+    _msgUtcTime_minutes <- getWord8
+    _msgUtcTime_seconds <- getWord8
+    _msgUtcTime_ns <- fromIntegral <$> getWord32le
+    return MsgUtcTime {..}
+
+  put MsgUtcTime {..} = do
+    putWord8 _msgUtcTime_flags
+    putWord32le _msgUtcTime_tow
+    putWord16le _msgUtcTime_year
+    putWord8 _msgUtcTime_month
+    putWord8 _msgUtcTime_day
+    putWord8 _msgUtcTime_hours
+    putWord8 _msgUtcTime_minutes
+    putWord8 _msgUtcTime_seconds
+    putWord32le $ fromIntegral _msgUtcTime_ns
+
+$(deriveSBP 'msgUtcTime ''MsgUtcTime)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgUtcTime_" . stripPrefix "_msgUtcTime_"}
+             ''MsgUtcTime)
+$(makeLenses ''MsgUtcTime)
+
 msgDops :: Word16
-msgDops = 0x0206
+msgDops = 0x0208
 
--- | SBP class for message MSG_DOPS (0x0206).
+-- | SBP class for message MSG_DOPS (0x0208).
 --
 -- This dilution of precision (DOP) message describes the effect of navigation
--- satellite geometry on positional measurement precision.
+-- satellite geometry on positional measurement precision.  The flags field
+-- indicated whether the DOP reported corresponds to differential or SPP
+-- solution.
 data MsgDops = MsgDops
   { _msgDops_tow :: Word32
     -- ^ GPS Time of Week
@@ -101,6 +163,8 @@
     -- ^ Horizontal Dilution of Precision
   , _msgDops_vdop :: Word16
     -- ^ Vertical Dilution of Precision
+  , _msgDops_flags :: Word8
+    -- ^ Indicates the position solution with which the DOPS message corresponds
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgDops where
@@ -111,6 +175,7 @@
     _msgDops_tdop <- getWord16le
     _msgDops_hdop <- getWord16le
     _msgDops_vdop <- getWord16le
+    _msgDops_flags <- getWord8
     return MsgDops {..}
 
   put MsgDops {..} = do
@@ -120,6 +185,7 @@
     putWord16le _msgDops_tdop
     putWord16le _msgDops_hdop
     putWord16le _msgDops_vdop
+    putWord8 _msgDops_flags
 
 $(deriveSBP 'msgDops ''MsgDops)
 
@@ -128,9 +194,9 @@
 $(makeLenses ''MsgDops)
 
 msgPosEcef :: Word16
-msgPosEcef = 0x0200
+msgPosEcef = 0x0209
 
--- | SBP class for message MSG_POS_ECEF (0x0200).
+-- | SBP class for message MSG_POS_ECEF (0x0209).
 --
 -- The position solution message reports absolute Earth Centered Earth Fixed
 -- (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of
@@ -149,7 +215,7 @@
   , _msgPosEcef_z      :: Double
     -- ^ ECEF Z coordinate
   , _msgPosEcef_accuracy :: Word16
-    -- ^ Position accuracy estimate (not implemented). Defaults to 0.
+    -- ^ Position accuracy estimate. Defaults to 0.
   , _msgPosEcef_n_sats :: Word8
     -- ^ Number of satellites used in solution
   , _msgPosEcef_flags  :: Word8
@@ -183,9 +249,9 @@
 $(makeLenses ''MsgPosEcef)
 
 msgPosLlh :: Word16
-msgPosLlh = 0x0201
+msgPosLlh = 0x020A
 
--- | SBP class for message MSG_POS_LLH (0x0201).
+-- | SBP class for message MSG_POS_LLH (0x020A).
 --
 -- This position solution message reports the absolute geodetic coordinates and
 -- the status (single point vs pseudo-absolute RTK) of the position solution.
@@ -242,9 +308,9 @@
 $(makeLenses ''MsgPosLlh)
 
 msgBaselineEcef :: Word16
-msgBaselineEcef = 0x0202
+msgBaselineEcef = 0x020B
 
--- | SBP class for message MSG_BASELINE_ECEF (0x0202).
+-- | SBP class for message MSG_BASELINE_ECEF (0x020B).
 --
 -- This message reports the baseline solution in Earth Centered Earth Fixed
 -- (ECEF) coordinates. This baseline is the relative vector distance from the
@@ -294,9 +360,9 @@
 $(makeLenses ''MsgBaselineEcef)
 
 msgBaselineNed :: Word16
-msgBaselineNed = 0x0203
+msgBaselineNed = 0x020C
 
--- | SBP class for message MSG_BASELINE_NED (0x0203).
+-- | SBP class for message MSG_BASELINE_NED (0x020C).
 --
 -- This message reports the baseline solution in North East Down (NED)
 -- coordinates. This baseline is the relative vector distance from the base
@@ -352,9 +418,9 @@
 $(makeLenses ''MsgBaselineNed)
 
 msgVelEcef :: Word16
-msgVelEcef = 0x0204
+msgVelEcef = 0x020D
 
--- | SBP class for message MSG_VEL_ECEF (0x0204).
+-- | SBP class for message MSG_VEL_ECEF (0x020D).
 --
 -- This message reports the velocity in Earth Centered Earth Fixed (ECEF)
 -- coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with
@@ -373,7 +439,7 @@
   , _msgVelEcef_n_sats :: Word8
     -- ^ Number of satellites used in solution
   , _msgVelEcef_flags  :: Word8
-    -- ^ Status flags (reserved)
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgVelEcef where
@@ -403,9 +469,9 @@
 $(makeLenses ''MsgVelEcef)
 
 msgVelNed :: Word16
-msgVelNed = 0x0205
+msgVelNed = 0x020E
 
--- | SBP class for message MSG_VEL_NED (0x0205).
+-- | SBP class for message MSG_VEL_NED (0x020E).
 --
 -- This message reports the velocity in local North East Down (NED)
 -- coordinates. The NED coordinate system is defined as the local WGS84 tangent
@@ -427,7 +493,7 @@
   , _msgVelNed_n_sats   :: Word8
     -- ^ Number of satellites used in solution
   , _msgVelNed_flags    :: Word8
-    -- ^ Status flags (reserved)
+    -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgVelNed where
@@ -459,13 +525,14 @@
 $(makeLenses ''MsgVelNed)
 
 msgBaselineHeading :: Word16
-msgBaselineHeading = 0x0207
+msgBaselineHeading = 0x020F
 
--- | SBP class for message MSG_BASELINE_HEADING (0x0207).
+-- | SBP class for message MSG_BASELINE_HEADING (0x020F).
 --
 -- This message reports the baseline heading pointing from the base station to
 -- the rover relative to True North. The full GPS time is given by the
--- preceding MSG_GPS_TIME with the matching time-of-week (tow).
+-- preceding MSG_GPS_TIME with the matching time-of-week (tow). It is intended
+-- that time-matched RTK mode is used when the base station is moving.
 data MsgBaselineHeading = MsgBaselineHeading
   { _msgBaselineHeading_tow   :: Word32
     -- ^ GPS Time of Week
@@ -496,3 +563,495 @@
 $(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgBaselineHeading_" . stripPrefix "_msgBaselineHeading_"}
              ''MsgBaselineHeading)
 $(makeLenses ''MsgBaselineHeading)
+
+msgAgeCorrections :: Word16
+msgAgeCorrections = 0x0210
+
+-- | SBP class for message MSG_AGE_CORRECTIONS (0x0210).
+--
+-- This message reports the Age of the corrections used for the current
+-- Differential solution
+data MsgAgeCorrections = MsgAgeCorrections
+  { _msgAgeCorrections_tow :: Word32
+    -- ^ GPS Time of Week
+  , _msgAgeCorrections_age :: Word16
+    -- ^ Age of the corrections (0xFFFF indicates invalid)
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgAgeCorrections where
+  get = do
+    _msgAgeCorrections_tow <- getWord32le
+    _msgAgeCorrections_age <- getWord16le
+    return MsgAgeCorrections {..}
+
+  put MsgAgeCorrections {..} = do
+    putWord32le _msgAgeCorrections_tow
+    putWord16le _msgAgeCorrections_age
+
+$(deriveSBP 'msgAgeCorrections ''MsgAgeCorrections)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgAgeCorrections_" . stripPrefix "_msgAgeCorrections_"}
+             ''MsgAgeCorrections)
+$(makeLenses ''MsgAgeCorrections)
+
+msgGpsTimeDepA :: Word16
+msgGpsTimeDepA = 0x0100
+
+-- | SBP class for message MSG_GPS_TIME_DEP_A (0x0100).
+--
+-- This message reports the GPS time, representing the time since the GPS epoch
+-- began on midnight January 6, 1980 UTC. GPS time counts the weeks and seconds
+-- of the week. The weeks begin at the Saturday/Sunday transition. GPS week 0
+-- began at the beginning of the GPS time scale.  Within each week number, the
+-- GPS time of the week is between between 0 and 604800 seconds (=60*60*24*7).
+-- Note that GPS time does not accumulate leap seconds, and as of now, has a
+-- small offset from UTC. In a message stream, this message precedes a set of
+-- other navigation messages referenced to the same time (but lacking the ns
+-- field) and indicates a more precise time of these messages.
+data MsgGpsTimeDepA = MsgGpsTimeDepA
+  { _msgGpsTimeDepA_wn  :: Word16
+    -- ^ GPS week number
+  , _msgGpsTimeDepA_tow :: Word32
+    -- ^ GPS time of week rounded to the nearest millisecond
+  , _msgGpsTimeDepA_ns  :: Int32
+    -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
+    -- 500000)
+  , _msgGpsTimeDepA_flags :: Word8
+    -- ^ Status flags (reserved)
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgGpsTimeDepA where
+  get = do
+    _msgGpsTimeDepA_wn <- getWord16le
+    _msgGpsTimeDepA_tow <- getWord32le
+    _msgGpsTimeDepA_ns <- fromIntegral <$> getWord32le
+    _msgGpsTimeDepA_flags <- getWord8
+    return MsgGpsTimeDepA {..}
+
+  put MsgGpsTimeDepA {..} = do
+    putWord16le _msgGpsTimeDepA_wn
+    putWord32le _msgGpsTimeDepA_tow
+    putWord32le $ fromIntegral _msgGpsTimeDepA_ns
+    putWord8 _msgGpsTimeDepA_flags
+
+$(deriveSBP 'msgGpsTimeDepA ''MsgGpsTimeDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgGpsTimeDepA_" . stripPrefix "_msgGpsTimeDepA_"}
+             ''MsgGpsTimeDepA)
+$(makeLenses ''MsgGpsTimeDepA)
+
+msgDopsDepA :: Word16
+msgDopsDepA = 0x0206
+
+-- | SBP class for message MSG_DOPS_DEP_A (0x0206).
+--
+-- This dilution of precision (DOP) message describes the effect of navigation
+-- satellite geometry on positional measurement precision.
+data MsgDopsDepA = MsgDopsDepA
+  { _msgDopsDepA_tow :: Word32
+    -- ^ GPS Time of Week
+  , _msgDopsDepA_gdop :: Word16
+    -- ^ Geometric Dilution of Precision
+  , _msgDopsDepA_pdop :: Word16
+    -- ^ Position Dilution of Precision
+  , _msgDopsDepA_tdop :: Word16
+    -- ^ Time Dilution of Precision
+  , _msgDopsDepA_hdop :: Word16
+    -- ^ Horizontal Dilution of Precision
+  , _msgDopsDepA_vdop :: Word16
+    -- ^ Vertical Dilution of Precision
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgDopsDepA where
+  get = do
+    _msgDopsDepA_tow <- getWord32le
+    _msgDopsDepA_gdop <- getWord16le
+    _msgDopsDepA_pdop <- getWord16le
+    _msgDopsDepA_tdop <- getWord16le
+    _msgDopsDepA_hdop <- getWord16le
+    _msgDopsDepA_vdop <- getWord16le
+    return MsgDopsDepA {..}
+
+  put MsgDopsDepA {..} = do
+    putWord32le _msgDopsDepA_tow
+    putWord16le _msgDopsDepA_gdop
+    putWord16le _msgDopsDepA_pdop
+    putWord16le _msgDopsDepA_tdop
+    putWord16le _msgDopsDepA_hdop
+    putWord16le _msgDopsDepA_vdop
+
+$(deriveSBP 'msgDopsDepA ''MsgDopsDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgDopsDepA_" . stripPrefix "_msgDopsDepA_"}
+             ''MsgDopsDepA)
+$(makeLenses ''MsgDopsDepA)
+
+msgPosEcefDepA :: Word16
+msgPosEcefDepA = 0x0200
+
+-- | SBP class for message MSG_POS_ECEF_DEP_A (0x0200).
+--
+-- The position solution message reports absolute Earth Centered Earth Fixed
+-- (ECEF) coordinates and the status (single point vs pseudo-absolute RTK) of
+-- the position solution. If the rover receiver knows the surveyed position of
+-- the base station and has an RTK solution, this reports a pseudo-absolute
+-- position solution using the base station position and the rover's RTK
+-- baseline vector. The full GPS time is given by the preceding MSG_GPS_TIME
+-- with the matching time-of-week (tow).
+data MsgPosEcefDepA = MsgPosEcefDepA
+  { _msgPosEcefDepA_tow    :: Word32
+    -- ^ GPS Time of Week
+  , _msgPosEcefDepA_x      :: Double
+    -- ^ ECEF X coordinate
+  , _msgPosEcefDepA_y      :: Double
+    -- ^ ECEF Y coordinate
+  , _msgPosEcefDepA_z      :: Double
+    -- ^ ECEF Z coordinate
+  , _msgPosEcefDepA_accuracy :: Word16
+    -- ^ Position accuracy estimate (not implemented). Defaults to 0.
+  , _msgPosEcefDepA_n_sats :: Word8
+    -- ^ Number of satellites used in solution
+  , _msgPosEcefDepA_flags  :: Word8
+    -- ^ Status flags
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgPosEcefDepA where
+  get = do
+    _msgPosEcefDepA_tow <- getWord32le
+    _msgPosEcefDepA_x <- getFloat64le
+    _msgPosEcefDepA_y <- getFloat64le
+    _msgPosEcefDepA_z <- getFloat64le
+    _msgPosEcefDepA_accuracy <- getWord16le
+    _msgPosEcefDepA_n_sats <- getWord8
+    _msgPosEcefDepA_flags <- getWord8
+    return MsgPosEcefDepA {..}
+
+  put MsgPosEcefDepA {..} = do
+    putWord32le _msgPosEcefDepA_tow
+    putFloat64le _msgPosEcefDepA_x
+    putFloat64le _msgPosEcefDepA_y
+    putFloat64le _msgPosEcefDepA_z
+    putWord16le _msgPosEcefDepA_accuracy
+    putWord8 _msgPosEcefDepA_n_sats
+    putWord8 _msgPosEcefDepA_flags
+
+$(deriveSBP 'msgPosEcefDepA ''MsgPosEcefDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgPosEcefDepA_" . stripPrefix "_msgPosEcefDepA_"}
+             ''MsgPosEcefDepA)
+$(makeLenses ''MsgPosEcefDepA)
+
+msgPosLlhDepA :: Word16
+msgPosLlhDepA = 0x0201
+
+-- | SBP class for message MSG_POS_LLH_DEP_A (0x0201).
+--
+-- This position solution message reports the absolute geodetic coordinates and
+-- the status (single point vs pseudo-absolute RTK) of the position solution.
+-- If the rover receiver knows the surveyed position of the base station and
+-- has an RTK solution, this reports a pseudo-absolute position solution using
+-- the base station position and the rover's RTK baseline vector. The full GPS
+-- time is given by the preceding MSG_GPS_TIME with the matching time-of-week
+-- (tow).
+data MsgPosLlhDepA = MsgPosLlhDepA
+  { _msgPosLlhDepA_tow      :: Word32
+    -- ^ GPS Time of Week
+  , _msgPosLlhDepA_lat      :: Double
+    -- ^ Latitude
+  , _msgPosLlhDepA_lon      :: Double
+    -- ^ Longitude
+  , _msgPosLlhDepA_height   :: Double
+    -- ^ Height
+  , _msgPosLlhDepA_h_accuracy :: Word16
+    -- ^ Horizontal position accuracy estimate (not implemented). Defaults to 0.
+  , _msgPosLlhDepA_v_accuracy :: Word16
+    -- ^ Vertical position accuracy estimate (not implemented). Defaults to 0.
+  , _msgPosLlhDepA_n_sats   :: Word8
+    -- ^ Number of satellites used in solution.
+  , _msgPosLlhDepA_flags    :: Word8
+    -- ^ Status flags
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgPosLlhDepA where
+  get = do
+    _msgPosLlhDepA_tow <- getWord32le
+    _msgPosLlhDepA_lat <- getFloat64le
+    _msgPosLlhDepA_lon <- getFloat64le
+    _msgPosLlhDepA_height <- getFloat64le
+    _msgPosLlhDepA_h_accuracy <- getWord16le
+    _msgPosLlhDepA_v_accuracy <- getWord16le
+    _msgPosLlhDepA_n_sats <- getWord8
+    _msgPosLlhDepA_flags <- getWord8
+    return MsgPosLlhDepA {..}
+
+  put MsgPosLlhDepA {..} = do
+    putWord32le _msgPosLlhDepA_tow
+    putFloat64le _msgPosLlhDepA_lat
+    putFloat64le _msgPosLlhDepA_lon
+    putFloat64le _msgPosLlhDepA_height
+    putWord16le _msgPosLlhDepA_h_accuracy
+    putWord16le _msgPosLlhDepA_v_accuracy
+    putWord8 _msgPosLlhDepA_n_sats
+    putWord8 _msgPosLlhDepA_flags
+
+$(deriveSBP 'msgPosLlhDepA ''MsgPosLlhDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgPosLlhDepA_" . stripPrefix "_msgPosLlhDepA_"}
+             ''MsgPosLlhDepA)
+$(makeLenses ''MsgPosLlhDepA)
+
+msgBaselineEcefDepA :: Word16
+msgBaselineEcefDepA = 0x0202
+
+-- | SBP class for message MSG_BASELINE_ECEF_DEP_A (0x0202).
+--
+-- This message reports the baseline solution in Earth Centered Earth Fixed
+-- (ECEF) coordinates. This baseline is the relative vector distance from the
+-- base station to the rover receiver. The full GPS time is given by the
+-- preceding MSG_GPS_TIME with the matching time-of-week (tow).
+data MsgBaselineEcefDepA = MsgBaselineEcefDepA
+  { _msgBaselineEcefDepA_tow    :: Word32
+    -- ^ GPS Time of Week
+  , _msgBaselineEcefDepA_x      :: Int32
+    -- ^ Baseline ECEF X coordinate
+  , _msgBaselineEcefDepA_y      :: Int32
+    -- ^ Baseline ECEF Y coordinate
+  , _msgBaselineEcefDepA_z      :: Int32
+    -- ^ Baseline ECEF Z coordinate
+  , _msgBaselineEcefDepA_accuracy :: Word16
+    -- ^ Position accuracy estimate (not implemented). Defaults to 0.
+  , _msgBaselineEcefDepA_n_sats :: Word8
+    -- ^ Number of satellites used in solution
+  , _msgBaselineEcefDepA_flags  :: Word8
+    -- ^ Status flags
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgBaselineEcefDepA where
+  get = do
+    _msgBaselineEcefDepA_tow <- getWord32le
+    _msgBaselineEcefDepA_x <- fromIntegral <$> getWord32le
+    _msgBaselineEcefDepA_y <- fromIntegral <$> getWord32le
+    _msgBaselineEcefDepA_z <- fromIntegral <$> getWord32le
+    _msgBaselineEcefDepA_accuracy <- getWord16le
+    _msgBaselineEcefDepA_n_sats <- getWord8
+    _msgBaselineEcefDepA_flags <- getWord8
+    return MsgBaselineEcefDepA {..}
+
+  put MsgBaselineEcefDepA {..} = do
+    putWord32le _msgBaselineEcefDepA_tow
+    putWord32le $ fromIntegral _msgBaselineEcefDepA_x
+    putWord32le $ fromIntegral _msgBaselineEcefDepA_y
+    putWord32le $ fromIntegral _msgBaselineEcefDepA_z
+    putWord16le _msgBaselineEcefDepA_accuracy
+    putWord8 _msgBaselineEcefDepA_n_sats
+    putWord8 _msgBaselineEcefDepA_flags
+
+$(deriveSBP 'msgBaselineEcefDepA ''MsgBaselineEcefDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgBaselineEcefDepA_" . stripPrefix "_msgBaselineEcefDepA_"}
+             ''MsgBaselineEcefDepA)
+$(makeLenses ''MsgBaselineEcefDepA)
+
+msgBaselineNedDepA :: Word16
+msgBaselineNedDepA = 0x0203
+
+-- | SBP class for message MSG_BASELINE_NED_DEP_A (0x0203).
+--
+-- This message reports the baseline solution in North East Down (NED)
+-- coordinates. This baseline is the relative vector distance from the base
+-- station to the rover receiver, and NED coordinate system is defined at the
+-- local WGS84 tangent plane centered at the base station position.  The full
+-- GPS time is given by the preceding MSG_GPS_TIME with the matching time-of-
+-- week (tow).
+data MsgBaselineNedDepA = MsgBaselineNedDepA
+  { _msgBaselineNedDepA_tow      :: Word32
+    -- ^ GPS Time of Week
+  , _msgBaselineNedDepA_n        :: Int32
+    -- ^ Baseline North coordinate
+  , _msgBaselineNedDepA_e        :: Int32
+    -- ^ Baseline East coordinate
+  , _msgBaselineNedDepA_d        :: Int32
+    -- ^ Baseline Down coordinate
+  , _msgBaselineNedDepA_h_accuracy :: Word16
+    -- ^ Horizontal position accuracy estimate (not implemented). Defaults to 0.
+  , _msgBaselineNedDepA_v_accuracy :: Word16
+    -- ^ Vertical position accuracy estimate (not implemented). Defaults to 0.
+  , _msgBaselineNedDepA_n_sats   :: Word8
+    -- ^ Number of satellites used in solution
+  , _msgBaselineNedDepA_flags    :: Word8
+    -- ^ Status flags
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgBaselineNedDepA where
+  get = do
+    _msgBaselineNedDepA_tow <- getWord32le
+    _msgBaselineNedDepA_n <- fromIntegral <$> getWord32le
+    _msgBaselineNedDepA_e <- fromIntegral <$> getWord32le
+    _msgBaselineNedDepA_d <- fromIntegral <$> getWord32le
+    _msgBaselineNedDepA_h_accuracy <- getWord16le
+    _msgBaselineNedDepA_v_accuracy <- getWord16le
+    _msgBaselineNedDepA_n_sats <- getWord8
+    _msgBaselineNedDepA_flags <- getWord8
+    return MsgBaselineNedDepA {..}
+
+  put MsgBaselineNedDepA {..} = do
+    putWord32le _msgBaselineNedDepA_tow
+    putWord32le $ fromIntegral _msgBaselineNedDepA_n
+    putWord32le $ fromIntegral _msgBaselineNedDepA_e
+    putWord32le $ fromIntegral _msgBaselineNedDepA_d
+    putWord16le _msgBaselineNedDepA_h_accuracy
+    putWord16le _msgBaselineNedDepA_v_accuracy
+    putWord8 _msgBaselineNedDepA_n_sats
+    putWord8 _msgBaselineNedDepA_flags
+
+$(deriveSBP 'msgBaselineNedDepA ''MsgBaselineNedDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgBaselineNedDepA_" . stripPrefix "_msgBaselineNedDepA_"}
+             ''MsgBaselineNedDepA)
+$(makeLenses ''MsgBaselineNedDepA)
+
+msgVelEcefDepA :: Word16
+msgVelEcefDepA = 0x0204
+
+-- | SBP class for message MSG_VEL_ECEF_DEP_A (0x0204).
+--
+-- This message reports the velocity in Earth Centered Earth Fixed (ECEF)
+-- coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with
+-- the matching time-of-week (tow).
+data MsgVelEcefDepA = MsgVelEcefDepA
+  { _msgVelEcefDepA_tow    :: Word32
+    -- ^ GPS Time of Week
+  , _msgVelEcefDepA_x      :: Int32
+    -- ^ Velocity ECEF X coordinate
+  , _msgVelEcefDepA_y      :: Int32
+    -- ^ Velocity ECEF Y coordinate
+  , _msgVelEcefDepA_z      :: Int32
+    -- ^ Velocity ECEF Z coordinate
+  , _msgVelEcefDepA_accuracy :: Word16
+    -- ^ Velocity accuracy estimate (not implemented). Defaults to 0.
+  , _msgVelEcefDepA_n_sats :: Word8
+    -- ^ Number of satellites used in solution
+  , _msgVelEcefDepA_flags  :: Word8
+    -- ^ Status flags (reserved)
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgVelEcefDepA where
+  get = do
+    _msgVelEcefDepA_tow <- getWord32le
+    _msgVelEcefDepA_x <- fromIntegral <$> getWord32le
+    _msgVelEcefDepA_y <- fromIntegral <$> getWord32le
+    _msgVelEcefDepA_z <- fromIntegral <$> getWord32le
+    _msgVelEcefDepA_accuracy <- getWord16le
+    _msgVelEcefDepA_n_sats <- getWord8
+    _msgVelEcefDepA_flags <- getWord8
+    return MsgVelEcefDepA {..}
+
+  put MsgVelEcefDepA {..} = do
+    putWord32le _msgVelEcefDepA_tow
+    putWord32le $ fromIntegral _msgVelEcefDepA_x
+    putWord32le $ fromIntegral _msgVelEcefDepA_y
+    putWord32le $ fromIntegral _msgVelEcefDepA_z
+    putWord16le _msgVelEcefDepA_accuracy
+    putWord8 _msgVelEcefDepA_n_sats
+    putWord8 _msgVelEcefDepA_flags
+
+$(deriveSBP 'msgVelEcefDepA ''MsgVelEcefDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgVelEcefDepA_" . stripPrefix "_msgVelEcefDepA_"}
+             ''MsgVelEcefDepA)
+$(makeLenses ''MsgVelEcefDepA)
+
+msgVelNedDepA :: Word16
+msgVelNedDepA = 0x0205
+
+-- | SBP class for message MSG_VEL_NED_DEP_A (0x0205).
+--
+-- This message reports the velocity in local North East Down (NED)
+-- coordinates. 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).
+data MsgVelNedDepA = MsgVelNedDepA
+  { _msgVelNedDepA_tow      :: Word32
+    -- ^ GPS Time of Week
+  , _msgVelNedDepA_n        :: Int32
+    -- ^ Velocity North coordinate
+  , _msgVelNedDepA_e        :: Int32
+    -- ^ Velocity East coordinate
+  , _msgVelNedDepA_d        :: Int32
+    -- ^ Velocity Down coordinate
+  , _msgVelNedDepA_h_accuracy :: Word16
+    -- ^ Horizontal velocity accuracy estimate (not implemented). Defaults to 0.
+  , _msgVelNedDepA_v_accuracy :: Word16
+    -- ^ Vertical velocity accuracy estimate (not implemented). Defaults to 0.
+  , _msgVelNedDepA_n_sats   :: Word8
+    -- ^ Number of satellites used in solution
+  , _msgVelNedDepA_flags    :: Word8
+    -- ^ Status flags (reserved)
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgVelNedDepA where
+  get = do
+    _msgVelNedDepA_tow <- getWord32le
+    _msgVelNedDepA_n <- fromIntegral <$> getWord32le
+    _msgVelNedDepA_e <- fromIntegral <$> getWord32le
+    _msgVelNedDepA_d <- fromIntegral <$> getWord32le
+    _msgVelNedDepA_h_accuracy <- getWord16le
+    _msgVelNedDepA_v_accuracy <- getWord16le
+    _msgVelNedDepA_n_sats <- getWord8
+    _msgVelNedDepA_flags <- getWord8
+    return MsgVelNedDepA {..}
+
+  put MsgVelNedDepA {..} = do
+    putWord32le _msgVelNedDepA_tow
+    putWord32le $ fromIntegral _msgVelNedDepA_n
+    putWord32le $ fromIntegral _msgVelNedDepA_e
+    putWord32le $ fromIntegral _msgVelNedDepA_d
+    putWord16le _msgVelNedDepA_h_accuracy
+    putWord16le _msgVelNedDepA_v_accuracy
+    putWord8 _msgVelNedDepA_n_sats
+    putWord8 _msgVelNedDepA_flags
+
+$(deriveSBP 'msgVelNedDepA ''MsgVelNedDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgVelNedDepA_" . stripPrefix "_msgVelNedDepA_"}
+             ''MsgVelNedDepA)
+$(makeLenses ''MsgVelNedDepA)
+
+msgBaselineHeadingDepA :: Word16
+msgBaselineHeadingDepA = 0x0207
+
+-- | SBP class for message MSG_BASELINE_HEADING_DEP_A (0x0207).
+--
+-- This message reports the baseline heading pointing from the base station to
+-- the rover relative to True North. The full GPS time is given by the
+-- preceding MSG_GPS_TIME with the matching time-of-week (tow).
+data MsgBaselineHeadingDepA = MsgBaselineHeadingDepA
+  { _msgBaselineHeadingDepA_tow   :: Word32
+    -- ^ GPS Time of Week
+  , _msgBaselineHeadingDepA_heading :: Word32
+    -- ^ Heading
+  , _msgBaselineHeadingDepA_n_sats :: Word8
+    -- ^ Number of satellites used in solution
+  , _msgBaselineHeadingDepA_flags :: Word8
+    -- ^ Status flags
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgBaselineHeadingDepA where
+  get = do
+    _msgBaselineHeadingDepA_tow <- getWord32le
+    _msgBaselineHeadingDepA_heading <- getWord32le
+    _msgBaselineHeadingDepA_n_sats <- getWord8
+    _msgBaselineHeadingDepA_flags <- getWord8
+    return MsgBaselineHeadingDepA {..}
+
+  put MsgBaselineHeadingDepA {..} = do
+    putWord32le _msgBaselineHeadingDepA_tow
+    putWord32le _msgBaselineHeadingDepA_heading
+    putWord8 _msgBaselineHeadingDepA_n_sats
+    putWord8 _msgBaselineHeadingDepA_flags
+
+$(deriveSBP 'msgBaselineHeadingDepA ''MsgBaselineHeadingDepA)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgBaselineHeadingDepA_" . stripPrefix "_msgBaselineHeadingDepA_"}
+             ''MsgBaselineHeadingDepA)
+$(makeLenses ''MsgBaselineHeadingDepA)
diff --git a/src/SwiftNav/SBP/Observation.hs b/src/SwiftNav/SBP/Observation.hs
--- a/src/SwiftNav/SBP/Observation.hs
+++ b/src/SwiftNav/SBP/Observation.hs
@@ -30,10 +30,10 @@
 
 -- | ObservationHeader.
 --
--- Header of a GPS observation message.
+-- Header of a GNSS observation message.
 data ObservationHeader = ObservationHeader
-  { _observationHeader_t   :: GpsTime
-    -- ^ GPS time of this observation
+  { _observationHeader_t   :: GpsTimeNano
+    -- ^ GNSS time of this observation
   , _observationHeader_n_obs :: Word8
     -- ^ Total number of observations. First nibble is the size of the sequence
     -- (n), second nibble is the zero-indexed counter (ith packet of n)
@@ -52,56 +52,102 @@
              ''ObservationHeader)
 $(makeLenses ''ObservationHeader)
 
+-- | Doppler.
+--
+-- Doppler measurement in Hz represented as a 24-bit fixed point number with
+-- Q16.8 layout, i.e. 16-bits of whole doppler and 8-bits of fractional
+-- doppler.  This doppler is defined as positive for approaching satellites.
+data Doppler = Doppler
+  { _doppler_i :: Int16
+    -- ^ Doppler whole Hz
+  , _doppler_f :: Word8
+    -- ^ Doppler fractional part
+  } deriving ( Show, Read, Eq )
+
+instance Binary Doppler where
+  get = do
+    _doppler_i <- fromIntegral <$> getWord16le
+    _doppler_f <- getWord8
+    return Doppler {..}
+
+  put Doppler {..} = do
+    putWord16le $ fromIntegral _doppler_i
+    putWord8 _doppler_f
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_doppler_" . stripPrefix "_doppler_"}
+             ''Doppler)
+$(makeLenses ''Doppler)
+
 -- | PackedObsContent.
 --
 -- Pseudorange and carrier phase observation for a satellite being tracked. The
--- observations should be interoperable with 3rd party receivers and conform
--- with typical RTCMv3 GNSS observations.
+-- observations are interoperable with 3rd party receivers and conform with
+-- typical RTCMv3 GNSS observations.
 data PackedObsContent = PackedObsContent
-  { _packedObsContent_P  :: Word32
+  { _packedObsContent_P   :: Word32
     -- ^ Pseudorange observation
-  , _packedObsContent_L  :: CarrierPhase
+  , _packedObsContent_L   :: CarrierPhase
     -- ^ Carrier phase observation with typical sign convention.
+  , _packedObsContent_D   :: Doppler
+    -- ^ Doppler observation with typical sign convention.
   , _packedObsContent_cn0 :: Word8
-    -- ^ Carrier-to-Noise density
-  , _packedObsContent_lock :: Word16
-    -- ^ Lock indicator. This value changes whenever a satellite signal has lost
-    -- and regained lock, indicating that the carrier phase ambiguity may have
-    -- changed.
-  , _packedObsContent_sid :: GnssSignal
-    -- ^ GNSS signal identifier
+    -- ^ Carrier-to-Noise density.  Zero implies invalid cn0.
+  , _packedObsContent_lock :: Word8
+    -- ^ Lock timer. This value gives an indication of the time for which a
+    -- signal has maintained continuous phase lock. Whenever a signal has lost
+    -- and regained lock, this  value is reset to zero. It is encoded according
+    -- to DF402 from the RTCM 10403.2 Amendment 2 specification.  Valid values
+    -- range  from 0 to 15 and the most significant nibble is reserved for
+    -- future use.
+  , _packedObsContent_flags :: Word8
+    -- ^ Measurement status flags. A bit field of flags providing the status of
+    -- this observation.  If this field is 0 it means only the Cn0 estimate for
+    -- the signal is valid.
+  , _packedObsContent_sid :: GnssSignal16
+    -- ^ GNSS signal identifier (16 bit)
   } deriving ( Show, Read, Eq )
 
 instance Binary PackedObsContent where
   get = do
     _packedObsContent_P <- getWord32le
     _packedObsContent_L <- get
+    _packedObsContent_D <- get
     _packedObsContent_cn0 <- getWord8
-    _packedObsContent_lock <- getWord16le
+    _packedObsContent_lock <- getWord8
+    _packedObsContent_flags <- getWord8
     _packedObsContent_sid <- get
     return PackedObsContent {..}
 
   put PackedObsContent {..} = do
     putWord32le _packedObsContent_P
     put _packedObsContent_L
+    put _packedObsContent_D
     putWord8 _packedObsContent_cn0
-    putWord16le _packedObsContent_lock
+    putWord8 _packedObsContent_lock
+    putWord8 _packedObsContent_flags
     put _packedObsContent_sid
 $(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_packedObsContent_" . stripPrefix "_packedObsContent_"}
              ''PackedObsContent)
 $(makeLenses ''PackedObsContent)
 
 msgObs :: Word16
-msgObs = 0x0049
+msgObs = 0x004A
 
--- | SBP class for message MSG_OBS (0x0049).
+-- | SBP class for message MSG_OBS (0x004A).
 --
 -- The GPS observations message reports all the raw pseudorange and carrier
 -- phase observations for the satellites being tracked by the device. Carrier
 -- phase observation here is represented as a 40-bit fixed point number with
 -- Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional cycles).
--- The observations should be interoperable with 3rd party receivers and
--- conform with typical RTCMv3 GNSS observations.
+-- The observations are be interoperable with 3rd party receivers and conform
+-- with typical RTCMv3 GNSS observations.    The lock field represents the
+-- range of time for  which a particular signal has maintained carrier phase
+-- lock.  The minimum and maximum possible lock times  for each value of the
+-- field can be described by the following piecewise function.   Given the lock
+-- value, l, the minimum lock time is given by 2 ^ (l + 4) ms and the  maximum
+-- lock time is given by 2 ^ (l + 5) ms provided n is not 0.   If n is 0 the
+-- lower range is given to be 0 ms. Conversely, given a lock time  (t) in
+-- milliseconds, the field value is given by floor(log_2(t) - 4)  when t is
+-- greater than 32 ms or 0 if (t) is less than 32 ms.
 data MsgObs = MsgObs
   { _msgObs_header :: ObservationHeader
     -- ^ Header of a GPS observation message
@@ -995,6 +1041,30 @@
              ''MsgEphemerisDepC)
 $(makeLenses ''MsgEphemerisDepC)
 
+-- | ObservationHeaderDep.
+--
+-- Header of a GPS observation message.
+data ObservationHeaderDep = ObservationHeaderDep
+  { _observationHeaderDep_t   :: GpsTime
+    -- ^ GPS time of this observation
+  , _observationHeaderDep_n_obs :: Word8
+    -- ^ Total number of observations. First nibble is the size of the sequence
+    -- (n), second nibble is the zero-indexed counter (ith packet of n)
+  } deriving ( Show, Read, Eq )
+
+instance Binary ObservationHeaderDep where
+  get = do
+    _observationHeaderDep_t <- get
+    _observationHeaderDep_n_obs <- getWord8
+    return ObservationHeaderDep {..}
+
+  put ObservationHeaderDep {..} = do
+    put _observationHeaderDep_t
+    putWord8 _observationHeaderDep_n_obs
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_observationHeaderDep_" . stripPrefix "_observationHeaderDep_"}
+             ''ObservationHeaderDep)
+$(makeLenses ''ObservationHeaderDep)
+
 -- | CarrierPhaseDepA.
 --
 -- Carrier phase measurement in cycles represented as a 40-bit fixed point
@@ -1096,6 +1166,45 @@
              ''PackedObsContentDepB)
 $(makeLenses ''PackedObsContentDepB)
 
+-- | PackedObsContentDepC.
+--
+-- Pseudorange and carrier phase observation for a satellite being tracked. The
+-- observations are be interoperable with 3rd party receivers and conform with
+-- typical RTCMv3 GNSS observations.
+data PackedObsContentDepC = PackedObsContentDepC
+  { _packedObsContentDepC_P  :: Word32
+    -- ^ Pseudorange observation
+  , _packedObsContentDepC_L  :: CarrierPhase
+    -- ^ Carrier phase observation with typical sign convention.
+  , _packedObsContentDepC_cn0 :: Word8
+    -- ^ Carrier-to-Noise density
+  , _packedObsContentDepC_lock :: Word16
+    -- ^ Lock indicator. This value changes whenever a satellite signal has lost
+    -- and regained lock, indicating that the carrier phase ambiguity may have
+    -- changed.
+  , _packedObsContentDepC_sid :: GnssSignal
+    -- ^ GNSS signal identifier
+  } deriving ( Show, Read, Eq )
+
+instance Binary PackedObsContentDepC where
+  get = do
+    _packedObsContentDepC_P <- getWord32le
+    _packedObsContentDepC_L <- get
+    _packedObsContentDepC_cn0 <- getWord8
+    _packedObsContentDepC_lock <- getWord16le
+    _packedObsContentDepC_sid <- get
+    return PackedObsContentDepC {..}
+
+  put PackedObsContentDepC {..} = do
+    putWord32le _packedObsContentDepC_P
+    put _packedObsContentDepC_L
+    putWord8 _packedObsContentDepC_cn0
+    putWord16le _packedObsContentDepC_lock
+    put _packedObsContentDepC_sid
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_packedObsContentDepC_" . stripPrefix "_packedObsContentDepC_"}
+             ''PackedObsContentDepC)
+$(makeLenses ''PackedObsContentDepC)
+
 msgObsDepA :: Word16
 msgObsDepA = 0x0045
 
@@ -1103,7 +1212,7 @@
 --
 -- Deprecated.
 data MsgObsDepA = MsgObsDepA
-  { _msgObsDepA_header :: ObservationHeader
+  { _msgObsDepA_header :: ObservationHeaderDep
     -- ^ Header of a GPS observation message
   , _msgObsDepA_obs  :: [PackedObsContentDepA]
     -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
@@ -1135,7 +1244,7 @@
 -- referenced to a nominal pseudorange which are not interoperable with most
 -- 3rd party GNSS receievers or typical RTCMv3 observations.
 data MsgObsDepB = MsgObsDepB
-  { _msgObsDepB_header :: ObservationHeader
+  { _msgObsDepB_header :: ObservationHeaderDep
     -- ^ Header of a GPS observation message
   , _msgObsDepB_obs  :: [PackedObsContentDepB]
     -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
@@ -1156,6 +1265,40 @@
 $(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgObsDepB_" . stripPrefix "_msgObsDepB_"}
              ''MsgObsDepB)
 $(makeLenses ''MsgObsDepB)
+
+msgObsDepC :: Word16
+msgObsDepC = 0x0049
+
+-- | SBP class for message MSG_OBS_DEP_C (0x0049).
+--
+-- The GPS observations message reports all the raw pseudorange and carrier
+-- phase observations for the satellites being tracked by the device. Carrier
+-- phase observation here is represented as a 40-bit fixed point number with
+-- Q32.8 layout (i.e. 32-bits of whole cycles and 8-bits of fractional cycles).
+-- The observations are interoperable with 3rd party receivers and conform with
+-- typical RTCMv3 GNSS observations.
+data MsgObsDepC = MsgObsDepC
+  { _msgObsDepC_header :: ObservationHeaderDep
+    -- ^ Header of a GPS observation message
+  , _msgObsDepC_obs  :: [PackedObsContentDepC]
+    -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgObsDepC where
+  get = do
+    _msgObsDepC_header <- get
+    _msgObsDepC_obs <- whileM (not <$> isEmpty) get
+    return MsgObsDepC {..}
+
+  put MsgObsDepC {..} = do
+    put _msgObsDepC_header
+    mapM_ put _msgObsDepC_obs
+
+$(deriveSBP 'msgObsDepC ''MsgObsDepC)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgObsDepC_" . stripPrefix "_msgObsDepC_"}
+             ''MsgObsDepC)
+$(makeLenses ''MsgObsDepC)
 
 msgIono :: Word16
 msgIono = 0x0090
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
@@ -36,23 +36,70 @@
 -- host or other attached devices that the system has started and is now ready
 -- to respond to commands or configuration requests.
 data MsgStartup = MsgStartup
-  { _msgStartup_reserved :: Word32
+  { _msgStartup_cause      :: Word8
+    -- ^ Cause of startup
+  , _msgStartup_startup_type :: Word8
+    -- ^ Startup type
+  , _msgStartup_reserved   :: Word16
     -- ^ Reserved
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgStartup where
   get = do
-    _msgStartup_reserved <- getWord32le
+    _msgStartup_cause <- getWord8
+    _msgStartup_startup_type <- getWord8
+    _msgStartup_reserved <- getWord16le
     return MsgStartup {..}
 
   put MsgStartup {..} = do
-    putWord32le _msgStartup_reserved
+    putWord8 _msgStartup_cause
+    putWord8 _msgStartup_startup_type
+    putWord16le _msgStartup_reserved
 
 $(deriveSBP 'msgStartup ''MsgStartup)
 
 $(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgStartup_" . stripPrefix "_msgStartup_"}
              ''MsgStartup)
 $(makeLenses ''MsgStartup)
+
+msgDgnssStatus :: Word16
+msgDgnssStatus = 0xFF02
+
+-- | SBP class for message MSG_DGNSS_STATUS (0xFF02).
+--
+-- This message provides information about the receipt of Differential
+-- corrections.  It is expected to be sent with each receipt of a complete
+-- corrections packet.
+data MsgDgnssStatus = MsgDgnssStatus
+  { _msgDgnssStatus_flags     :: Word8
+    -- ^ Status flags
+  , _msgDgnssStatus_latency   :: Word16
+    -- ^ Latency of observation receipt
+  , _msgDgnssStatus_num_signals :: Word8
+    -- ^ Number of signals from base station
+  , _msgDgnssStatus_source    :: Text
+    -- ^ Corrections source string
+  } deriving ( Show, Read, Eq )
+
+instance Binary MsgDgnssStatus where
+  get = do
+    _msgDgnssStatus_flags <- getWord8
+    _msgDgnssStatus_latency <- getWord16le
+    _msgDgnssStatus_num_signals <- getWord8
+    _msgDgnssStatus_source <- decodeUtf8 . toStrict <$> getRemainingLazyByteString
+    return MsgDgnssStatus {..}
+
+  put MsgDgnssStatus {..} = do
+    putWord8 _msgDgnssStatus_flags
+    putWord16le _msgDgnssStatus_latency
+    putWord8 _msgDgnssStatus_num_signals
+    putByteString $ encodeUtf8 _msgDgnssStatus_source
+
+$(deriveSBP 'msgDgnssStatus ''MsgDgnssStatus)
+
+$(deriveJSON defaultOptions {fieldLabelModifier = fromMaybe "_msgDgnssStatus_" . stripPrefix "_msgDgnssStatus_"}
+             ''MsgDgnssStatus)
+$(makeLenses ''MsgDgnssStatus)
 
 msgHeartbeat :: Word16
 msgHeartbeat = 0xFFFF
