-- | -- Module: SwiftNav.SBP -- Copyright: Copyright (C) 2015 Swift Navigation, Inc. -- License: LGPL-3 -- Maintainer: Mark Fine -- Stability: experimental -- Portability: portable -- -- SBP message containers. module SwiftNav.SBP ( Msg (..) , SBPMsg (..) , msgSBPPreamble , defaultSender , module SwiftNav.SBP.Acquisition , module SwiftNav.SBP.Bootload , module SwiftNav.SBP.ExtEvents , module SwiftNav.SBP.FileIo , module SwiftNav.SBP.Flash , module SwiftNav.SBP.Logging , module SwiftNav.SBP.Navigation , module SwiftNav.SBP.Observation , module SwiftNav.SBP.Piksi , module SwiftNav.SBP.Settings , module SwiftNav.SBP.System , module SwiftNav.SBP.Tracking ) 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 -- | Denotes the start of frame transmission. For v1.0, always 0x55. msgSBPPreamble :: Word8 msgSBPPreamble = 0x55 -- | Default sender ID. Intended for messages sent from the host to -- the device. defaultSender :: Word16 defaultSender = 0x42 -- | Packet structure for Swift Navigation Binary Protocol (SBP). -- -- Definition of the over-the-wire message framing format and packet -- structure for Swift Navigation Binary Protocol (SBP), a minimal -- binary protocol for communicating with Swift devices. It is used -- to transmit solutions, observations, status and debugging -- messages, as well as receive messages from the host operating -- system. data Msg = Msg { _msgSBPType :: Word16 -- ^ Uniquely identifies the type of the payload contents , _msgSBPSender :: Word16 -- ^ A unique identifier of the sending hardware. For v1.0, -- set to the 2 least significant bytes of the device serial -- number , _msgSBPLen :: Word8 -- ^ Byte-length of the payload field , _msgSBPPayload :: !ByteString -- ^ Binary data of the message, as identified by Message Type and -- Length. Usually contains the in-memory binary representation of -- a C struct (see documentation on individual message types) , _msgSBPCrc :: Word16 -- ^ Cyclic Redundancy Check (CRC) of the packet's binary data from -- the Message Type up to the end of Payload (does not include the -- Preamble) } 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" .= msgSBPPreamble , "msg_type" .= _msgSBPType , "sender" .= _msgSBPSender , "length" .= _msgSBPLen , "payload" .= _msgSBPPayload , "crc" .= _msgSBPCrc ] -- | An SBP message ADT composed of all defined SBP messages. -- -- Includes SBPMsgUnknown for valid SBP messages with undefined message -- types and SBPMsgBadCRC for SBP messages with invalid CRC checksums. 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 /= msgSBPPreamble 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 msgSBPPreamble 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