module SwiftNav.SBP where
import BasicPrelude hiding (lookup)
import Control.Lens hiding ((.=))
import Data.Aeson hiding (decode, decode')
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import Data.ByteString.Lazy hiding (ByteString)
import Data.ByteString.Builder
import Data.HashMap.Strict
import SwiftNav.CRC16
import SwiftNav.SBP.Acquisition
import SwiftNav.SBP.Bootload
import SwiftNav.SBP.ExtEvents
import SwiftNav.SBP.FileIo
import SwiftNav.SBP.Flash
import SwiftNav.SBP.Logging
import SwiftNav.SBP.Navigation
import SwiftNav.SBP.Observation
import SwiftNav.SBP.Piksi
import SwiftNav.SBP.Settings
import SwiftNav.SBP.System
import SwiftNav.SBP.Tracking
msgPreamble :: Word8
msgPreamble = 0x55
defaultSenderID :: Word16
defaultSenderID = 0x42
data Msg = Msg
{ _msgSBPType :: Word16
, _msgSBPSender :: Word16
, _msgSBPLen :: Word8
, _msgSBPPayload :: !ByteString
, _msgSBPCrc :: Word16
} deriving ( Show, Read, Eq )
$(makeLenses ''Msg)
instance Binary Msg where
get = do
_msgSBPType <- getWord16le
_msgSBPSender <- getWord16le
_msgSBPLen <- getWord8
_msgSBPPayload <- getByteString $ fromIntegral _msgSBPLen
_msgSBPCrc <- getWord16le
return Msg {..}
put Msg {..} = do
putWord16le _msgSBPType
putWord16le _msgSBPSender
putWord8 _msgSBPLen
putByteString _msgSBPPayload
putWord16le _msgSBPCrc
checkCrc :: Msg -> Word16
checkCrc Msg {..} =
crc16 $ toLazyByteString $
word16LE _msgSBPType <>
word16LE _msgSBPSender <>
word8 _msgSBPLen <>
byteString _msgSBPPayload
instance FromJSON Msg where
parseJSON (Object v) = do
Msg <$> v .: "msg_type"
<*> v .: "sender"
<*> v .: "length"
<*> v .: "payload"
<*> v .: "crc"
parseJSON _ = mzero
instance ToJSON Msg where
toJSON Msg {..} = object
[ "preamble" .= msgPreamble
, "msg_type" .= _msgSBPType
, "sender" .= _msgSBPSender
, "length" .= _msgSBPLen
, "payload" .= _msgSBPPayload
, "crc" .= _msgSBPCrc
]
data SBPMsg =
SBPMsgAcqResult MsgAcqResult Msg
| SBPMsgAcqResultDepA MsgAcqResultDepA Msg
| SBPMsgAlmanac MsgAlmanac Msg
| SBPMsgBasePos MsgBasePos Msg
| SBPMsgBaselineEcef MsgBaselineEcef Msg
| SBPMsgBaselineNed MsgBaselineNed Msg
| SBPMsgBootloaderHandshakeDepA MsgBootloaderHandshakeDepA Msg
| SBPMsgBootloaderHandshakeReq MsgBootloaderHandshakeReq Msg
| SBPMsgBootloaderHandshakeResp MsgBootloaderHandshakeResp Msg
| SBPMsgBootloaderJumpToApp MsgBootloaderJumpToApp Msg
| SBPMsgCwResults MsgCwResults Msg
| SBPMsgCwStart MsgCwStart Msg
| SBPMsgDops MsgDops Msg
| SBPMsgEphemeris MsgEphemeris Msg
| SBPMsgEphemerisDepA MsgEphemerisDepA Msg
| SBPMsgEphemerisDepB MsgEphemerisDepB Msg
| SBPMsgExtEvent MsgExtEvent Msg
| SBPMsgFileioReadDirReq MsgFileioReadDirReq Msg
| SBPMsgFileioReadDirResp MsgFileioReadDirResp Msg
| SBPMsgFileioReadReq MsgFileioReadReq Msg
| SBPMsgFileioReadResp MsgFileioReadResp Msg
| SBPMsgFileioRemove MsgFileioRemove Msg
| SBPMsgFileioWriteReq MsgFileioWriteReq Msg
| SBPMsgFileioWriteResp MsgFileioWriteResp Msg
| SBPMsgFlashDone MsgFlashDone Msg
| SBPMsgFlashErase MsgFlashErase Msg
| SBPMsgFlashProgram MsgFlashProgram Msg
| SBPMsgFlashReadReq MsgFlashReadReq Msg
| SBPMsgFlashReadResp MsgFlashReadResp Msg
| SBPMsgGpsTime MsgGpsTime Msg
| SBPMsgHeartbeat MsgHeartbeat Msg
| SBPMsgIarState MsgIarState Msg
| SBPMsgInitBase MsgInitBase Msg
| SBPMsgLog MsgLog Msg
| SBPMsgM25FlashWriteStatus MsgM25FlashWriteStatus Msg
| SBPMsgMaskSatellite MsgMaskSatellite Msg
| SBPMsgNapDeviceDnaReq MsgNapDeviceDnaReq Msg
| SBPMsgNapDeviceDnaResp MsgNapDeviceDnaResp Msg
| SBPMsgObs MsgObs Msg
| SBPMsgObsDepA MsgObsDepA Msg
| SBPMsgPosEcef MsgPosEcef Msg
| SBPMsgPosLlh MsgPosLlh Msg
| SBPMsgPrintDep MsgPrintDep Msg
| SBPMsgReset MsgReset Msg
| SBPMsgResetFilters MsgResetFilters Msg
| SBPMsgSetTime MsgSetTime Msg
| SBPMsgSettingsReadByIndexDone MsgSettingsReadByIndexDone Msg
| SBPMsgSettingsReadByIndexReq MsgSettingsReadByIndexReq Msg
| SBPMsgSettingsReadByIndexResp MsgSettingsReadByIndexResp Msg
| SBPMsgSettingsReadReq MsgSettingsReadReq Msg
| SBPMsgSettingsReadResp MsgSettingsReadResp Msg
| SBPMsgSettingsSave MsgSettingsSave Msg
| SBPMsgSettingsWrite MsgSettingsWrite Msg
| SBPMsgStartup MsgStartup Msg
| SBPMsgStmFlashLockSector MsgStmFlashLockSector Msg
| SBPMsgStmFlashUnlockSector MsgStmFlashUnlockSector Msg
| SBPMsgStmUniqueIdReq MsgStmUniqueIdReq Msg
| SBPMsgStmUniqueIdResp MsgStmUniqueIdResp Msg
| SBPMsgThreadState MsgThreadState Msg
| SBPMsgTrackingIq MsgTrackingIq Msg
| SBPMsgTrackingState MsgTrackingState Msg
| SBPMsgTrackingStateDepA MsgTrackingStateDepA Msg
| SBPMsgTweet MsgTweet Msg
| SBPMsgUartState MsgUartState Msg
| SBPMsgVelEcef MsgVelEcef Msg
| SBPMsgVelNed MsgVelNed Msg
| SBPMsgBadCrc Msg
| SBPMsgUnknown Msg
deriving ( Show, Read, Eq )
instance Binary SBPMsg where
get = do
preamble <- getWord8
if preamble /= msgPreamble then get else do
sbp <- get
return $ decode' sbp where
decode' sbp@Msg {..}
| checkCrc sbp /= _msgSBPCrc = SBPMsgBadCrc sbp
| _msgSBPType == msgAcqResult = SBPMsgAcqResult (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgAcqResultDepA = SBPMsgAcqResultDepA (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgAlmanac = SBPMsgAlmanac (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBasePos = SBPMsgBasePos (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBaselineEcef = SBPMsgBaselineEcef (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBaselineNed = SBPMsgBaselineNed (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBootloaderHandshakeDepA = SBPMsgBootloaderHandshakeDepA (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBootloaderHandshakeReq = SBPMsgBootloaderHandshakeReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBootloaderHandshakeResp = SBPMsgBootloaderHandshakeResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgBootloaderJumpToApp = SBPMsgBootloaderJumpToApp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgCwResults = SBPMsgCwResults (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgCwStart = SBPMsgCwStart (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgDops = SBPMsgDops (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgEphemeris = SBPMsgEphemeris (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgEphemerisDepA = SBPMsgEphemerisDepA (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgEphemerisDepB = SBPMsgEphemerisDepB (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgExtEvent = SBPMsgExtEvent (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioReadDirReq = SBPMsgFileioReadDirReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioReadDirResp = SBPMsgFileioReadDirResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioReadReq = SBPMsgFileioReadReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioReadResp = SBPMsgFileioReadResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioRemove = SBPMsgFileioRemove (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioWriteReq = SBPMsgFileioWriteReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFileioWriteResp = SBPMsgFileioWriteResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFlashDone = SBPMsgFlashDone (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFlashErase = SBPMsgFlashErase (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFlashProgram = SBPMsgFlashProgram (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFlashReadReq = SBPMsgFlashReadReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgFlashReadResp = SBPMsgFlashReadResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgGpsTime = SBPMsgGpsTime (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgHeartbeat = SBPMsgHeartbeat (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgIarState = SBPMsgIarState (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgInitBase = SBPMsgInitBase (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgLog = SBPMsgLog (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgM25FlashWriteStatus = SBPMsgM25FlashWriteStatus (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgMaskSatellite = SBPMsgMaskSatellite (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgNapDeviceDnaReq = SBPMsgNapDeviceDnaReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgNapDeviceDnaResp = SBPMsgNapDeviceDnaResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgObs = SBPMsgObs (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgObsDepA = SBPMsgObsDepA (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgPosEcef = SBPMsgPosEcef (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgPosLlh = SBPMsgPosLlh (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgPrintDep = SBPMsgPrintDep (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgReset = SBPMsgReset (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgResetFilters = SBPMsgResetFilters (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSetTime = SBPMsgSetTime (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsReadByIndexDone = SBPMsgSettingsReadByIndexDone (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsReadByIndexReq = SBPMsgSettingsReadByIndexReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsReadByIndexResp = SBPMsgSettingsReadByIndexResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsReadReq = SBPMsgSettingsReadReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsReadResp = SBPMsgSettingsReadResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsSave = SBPMsgSettingsSave (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgSettingsWrite = SBPMsgSettingsWrite (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgStartup = SBPMsgStartup (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgStmFlashLockSector = SBPMsgStmFlashLockSector (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgStmFlashUnlockSector = SBPMsgStmFlashUnlockSector (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgStmUniqueIdReq = SBPMsgStmUniqueIdReq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgStmUniqueIdResp = SBPMsgStmUniqueIdResp (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgThreadState = SBPMsgThreadState (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgTrackingIq = SBPMsgTrackingIq (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgTrackingState = SBPMsgTrackingState (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgTrackingStateDepA = SBPMsgTrackingStateDepA (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgTweet = SBPMsgTweet (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgUartState = SBPMsgUartState (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgVelEcef = SBPMsgVelEcef (decode (fromStrict _msgSBPPayload)) sbp
| _msgSBPType == msgVelNed = SBPMsgVelNed (decode (fromStrict _msgSBPPayload)) sbp
| otherwise = SBPMsgUnknown sbp
put msg = do
putWord8 msgPreamble
put $ encode' msg
where
encode' (SBPMsgAcqResult _ sbp) = sbp
encode' (SBPMsgAcqResultDepA _ sbp) = sbp
encode' (SBPMsgAlmanac _ sbp) = sbp
encode' (SBPMsgBasePos _ sbp) = sbp
encode' (SBPMsgBaselineEcef _ sbp) = sbp
encode' (SBPMsgBaselineNed _ sbp) = sbp
encode' (SBPMsgBootloaderHandshakeDepA _ sbp) = sbp
encode' (SBPMsgBootloaderHandshakeReq _ sbp) = sbp
encode' (SBPMsgBootloaderHandshakeResp _ sbp) = sbp
encode' (SBPMsgBootloaderJumpToApp _ sbp) = sbp
encode' (SBPMsgCwResults _ sbp) = sbp
encode' (SBPMsgCwStart _ sbp) = sbp
encode' (SBPMsgDops _ sbp) = sbp
encode' (SBPMsgEphemeris _ sbp) = sbp
encode' (SBPMsgEphemerisDepA _ sbp) = sbp
encode' (SBPMsgEphemerisDepB _ sbp) = sbp
encode' (SBPMsgExtEvent _ sbp) = sbp
encode' (SBPMsgFileioReadDirReq _ sbp) = sbp
encode' (SBPMsgFileioReadDirResp _ sbp) = sbp
encode' (SBPMsgFileioReadReq _ sbp) = sbp
encode' (SBPMsgFileioReadResp _ sbp) = sbp
encode' (SBPMsgFileioRemove _ sbp) = sbp
encode' (SBPMsgFileioWriteReq _ sbp) = sbp
encode' (SBPMsgFileioWriteResp _ sbp) = sbp
encode' (SBPMsgFlashDone _ sbp) = sbp
encode' (SBPMsgFlashErase _ sbp) = sbp
encode' (SBPMsgFlashProgram _ sbp) = sbp
encode' (SBPMsgFlashReadReq _ sbp) = sbp
encode' (SBPMsgFlashReadResp _ sbp) = sbp
encode' (SBPMsgGpsTime _ sbp) = sbp
encode' (SBPMsgHeartbeat _ sbp) = sbp
encode' (SBPMsgIarState _ sbp) = sbp
encode' (SBPMsgInitBase _ sbp) = sbp
encode' (SBPMsgLog _ sbp) = sbp
encode' (SBPMsgM25FlashWriteStatus _ sbp) = sbp
encode' (SBPMsgMaskSatellite _ sbp) = sbp
encode' (SBPMsgNapDeviceDnaReq _ sbp) = sbp
encode' (SBPMsgNapDeviceDnaResp _ sbp) = sbp
encode' (SBPMsgObs _ sbp) = sbp
encode' (SBPMsgObsDepA _ sbp) = sbp
encode' (SBPMsgPosEcef _ sbp) = sbp
encode' (SBPMsgPosLlh _ sbp) = sbp
encode' (SBPMsgPrintDep _ sbp) = sbp
encode' (SBPMsgReset _ sbp) = sbp
encode' (SBPMsgResetFilters _ sbp) = sbp
encode' (SBPMsgSetTime _ sbp) = sbp
encode' (SBPMsgSettingsReadByIndexDone _ sbp) = sbp
encode' (SBPMsgSettingsReadByIndexReq _ sbp) = sbp
encode' (SBPMsgSettingsReadByIndexResp _ sbp) = sbp
encode' (SBPMsgSettingsReadReq _ sbp) = sbp
encode' (SBPMsgSettingsReadResp _ sbp) = sbp
encode' (SBPMsgSettingsSave _ sbp) = sbp
encode' (SBPMsgSettingsWrite _ sbp) = sbp
encode' (SBPMsgStartup _ sbp) = sbp
encode' (SBPMsgStmFlashLockSector _ sbp) = sbp
encode' (SBPMsgStmFlashUnlockSector _ sbp) = sbp
encode' (SBPMsgStmUniqueIdReq _ sbp) = sbp
encode' (SBPMsgStmUniqueIdResp _ sbp) = sbp
encode' (SBPMsgThreadState _ sbp) = sbp
encode' (SBPMsgTrackingIq _ sbp) = sbp
encode' (SBPMsgTrackingState _ sbp) = sbp
encode' (SBPMsgTrackingStateDepA _ sbp) = sbp
encode' (SBPMsgTweet _ sbp) = sbp
encode' (SBPMsgUartState _ sbp) = sbp
encode' (SBPMsgVelEcef _ sbp) = sbp
encode' (SBPMsgVelNed _ sbp) = sbp
encode' (SBPMsgUnknown sbp) = sbp
encode' (SBPMsgBadCrc sbp) = sbp
instance FromJSON SBPMsg where
parseJSON obj@(Object o) = do
msgType <- o .: "msg_type"
decode' msgType where
decode' msgType
| msgType == msgAcqResult = SBPMsgAcqResult <$> parseJSON obj <*> parseJSON obj
| msgType == msgAcqResultDepA = SBPMsgAcqResultDepA <$> parseJSON obj <*> parseJSON obj
| msgType == msgAlmanac = SBPMsgAlmanac <$> parseJSON obj <*> parseJSON obj
| msgType == msgBasePos = SBPMsgBasePos <$> parseJSON obj <*> parseJSON obj
| msgType == msgBaselineEcef = SBPMsgBaselineEcef <$> parseJSON obj <*> parseJSON obj
| msgType == msgBaselineNed = SBPMsgBaselineNed <$> 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
| msgType == msgBootloaderJumpToApp = SBPMsgBootloaderJumpToApp <$> parseJSON obj <*> parseJSON obj
| msgType == msgCwResults = SBPMsgCwResults <$> parseJSON obj <*> parseJSON obj
| msgType == msgCwStart = SBPMsgCwStart <$> parseJSON obj <*> parseJSON obj
| msgType == msgDops = SBPMsgDops <$> parseJSON obj <*> parseJSON obj
| msgType == msgEphemeris = SBPMsgEphemeris <$> parseJSON obj <*> parseJSON obj
| msgType == msgEphemerisDepA = SBPMsgEphemerisDepA <$> parseJSON obj <*> parseJSON obj
| msgType == msgEphemerisDepB = SBPMsgEphemerisDepB <$> parseJSON obj <*> parseJSON obj
| msgType == msgExtEvent = SBPMsgExtEvent <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioReadDirReq = SBPMsgFileioReadDirReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioReadDirResp = SBPMsgFileioReadDirResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioReadReq = SBPMsgFileioReadReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioReadResp = SBPMsgFileioReadResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioRemove = SBPMsgFileioRemove <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioWriteReq = SBPMsgFileioWriteReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgFileioWriteResp = SBPMsgFileioWriteResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgFlashDone = SBPMsgFlashDone <$> parseJSON obj <*> parseJSON obj
| msgType == msgFlashErase = SBPMsgFlashErase <$> parseJSON obj <*> parseJSON obj
| msgType == msgFlashProgram = SBPMsgFlashProgram <$> parseJSON obj <*> parseJSON obj
| msgType == msgFlashReadReq = SBPMsgFlashReadReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgFlashReadResp = SBPMsgFlashReadResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgGpsTime = SBPMsgGpsTime <$> parseJSON obj <*> parseJSON obj
| msgType == msgHeartbeat = SBPMsgHeartbeat <$> parseJSON obj <*> parseJSON obj
| msgType == msgIarState = SBPMsgIarState <$> parseJSON obj <*> parseJSON obj
| msgType == msgInitBase = SBPMsgInitBase <$> parseJSON obj <*> parseJSON obj
| msgType == msgLog = SBPMsgLog <$> parseJSON obj <*> parseJSON obj
| msgType == msgM25FlashWriteStatus = SBPMsgM25FlashWriteStatus <$> parseJSON obj <*> parseJSON obj
| msgType == msgMaskSatellite = SBPMsgMaskSatellite <$> parseJSON obj <*> parseJSON obj
| msgType == msgNapDeviceDnaReq = SBPMsgNapDeviceDnaReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgNapDeviceDnaResp = SBPMsgNapDeviceDnaResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgObs = SBPMsgObs <$> parseJSON obj <*> parseJSON obj
| msgType == msgObsDepA = SBPMsgObsDepA <$> parseJSON obj <*> parseJSON obj
| msgType == msgPosEcef = SBPMsgPosEcef <$> parseJSON obj <*> parseJSON obj
| msgType == msgPosLlh = SBPMsgPosLlh <$> 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
| msgType == msgSetTime = SBPMsgSetTime <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsReadByIndexDone = SBPMsgSettingsReadByIndexDone <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsReadByIndexReq = SBPMsgSettingsReadByIndexReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsReadByIndexResp = SBPMsgSettingsReadByIndexResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsReadReq = SBPMsgSettingsReadReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsReadResp = SBPMsgSettingsReadResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsSave = SBPMsgSettingsSave <$> parseJSON obj <*> parseJSON obj
| msgType == msgSettingsWrite = SBPMsgSettingsWrite <$> parseJSON obj <*> parseJSON obj
| msgType == msgStartup = SBPMsgStartup <$> parseJSON obj <*> parseJSON obj
| msgType == msgStmFlashLockSector = SBPMsgStmFlashLockSector <$> parseJSON obj <*> parseJSON obj
| msgType == msgStmFlashUnlockSector = SBPMsgStmFlashUnlockSector <$> parseJSON obj <*> parseJSON obj
| msgType == msgStmUniqueIdReq = SBPMsgStmUniqueIdReq <$> parseJSON obj <*> parseJSON obj
| msgType == msgStmUniqueIdResp = SBPMsgStmUniqueIdResp <$> parseJSON obj <*> parseJSON obj
| msgType == msgThreadState = SBPMsgThreadState <$> parseJSON obj <*> parseJSON obj
| msgType == msgTrackingIq = SBPMsgTrackingIq <$> parseJSON obj <*> parseJSON obj
| msgType == msgTrackingState = SBPMsgTrackingState <$> parseJSON obj <*> parseJSON obj
| msgType == msgTrackingStateDepA = SBPMsgTrackingStateDepA <$> parseJSON obj <*> parseJSON obj
| msgType == msgTweet = SBPMsgTweet <$> parseJSON obj <*> parseJSON obj
| msgType == msgUartState = SBPMsgUartState <$> parseJSON obj <*> parseJSON obj
| msgType == msgVelEcef = SBPMsgVelEcef <$> parseJSON obj <*> parseJSON obj
| msgType == msgVelNed = SBPMsgVelNed <$> parseJSON obj <*> parseJSON obj
| otherwise = SBPMsgUnknown <$> parseJSON obj
parseJSON _ = mzero
merge :: Value -> Value -> Value
merge (Object one) (Object two) = Object (one <> two)
merge _ (Object two) = Object two
merge (Object one) _ = Object one
merge _ v = v
instance ToJSON SBPMsg where
toJSON (SBPMsgAcqResult msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgAcqResultDepA msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgAlmanac msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBasePos msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBaselineEcef msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBaselineNed msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBootloaderHandshakeDepA msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBootloaderHandshakeReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBootloaderHandshakeResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBootloaderJumpToApp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgCwResults msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgCwStart msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgDops msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgEphemeris msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgEphemerisDepA msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgEphemerisDepB msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgExtEvent msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioReadDirReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioReadDirResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioReadReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioReadResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioRemove msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioWriteReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFileioWriteResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFlashDone msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFlashErase msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFlashProgram msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFlashReadReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgFlashReadResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgGpsTime msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgHeartbeat msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgIarState msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgInitBase msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgLog msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgM25FlashWriteStatus msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgMaskSatellite msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgNapDeviceDnaReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgNapDeviceDnaResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgObs msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgObsDepA msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgPosEcef msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgPosLlh msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgPrintDep msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgReset msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgResetFilters msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSetTime msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsReadByIndexDone msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsReadByIndexReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsReadByIndexResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsReadReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsReadResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsSave msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgSettingsWrite msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgStartup msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgStmFlashLockSector msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgStmFlashUnlockSector msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgStmUniqueIdReq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgStmUniqueIdResp msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgThreadState msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgTrackingIq msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgTrackingState msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgTrackingStateDepA msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgTweet msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgUartState msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgVelEcef msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgVelNed msg sbp) = toJSON msg `merge` toJSON sbp
toJSON (SBPMsgBadCrc sbp) = toJSON sbp
toJSON (SBPMsgUnknown sbp) = toJSON sbp