packages feed

sbp-6.3.2: src/SwiftNav/SBP/Signing.hs

{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# LANGUAGE NoImplicitPrelude           #-}
{-# LANGUAGE TemplateHaskell             #-}
{-# LANGUAGE RecordWildCards             #-}

-- |
-- Module:      SwiftNav.SBP.Signing
-- Copyright:   Copyright (C) 2015-2021 Swift Navigation, Inc.
-- License:     MIT
-- Contact:     https://support.swiftnav.com
-- Stability:   experimental
-- Portability: portable
--
-- \< Messages relating to signatures \>

module SwiftNav.SBP.Signing
  ( module SwiftNav.SBP.Signing
  ) where

import BasicPrelude
import Control.Lens
import Control.Monad.Loops
import Data.Binary
import Data.Binary.Get
import Data.Binary.IEEE754
import Data.Binary.Put
import Data.ByteString.Lazy    hiding (ByteString)
import Data.Int
import Data.Word
import SwiftNav.SBP.TH
import SwiftNav.SBP.Types

{-# ANN module ("HLint: ignore Use camelCase"::String) #-}
{-# ANN module ("HLint: ignore Redundant do"::String) #-}
{-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-}


data UtcTime = UtcTime
  { _utcTime_year  :: !Word16
    -- ^ Year
  , _utcTime_month :: !Word8
    -- ^ Month (range 1 .. 12)
  , _utcTime_day   :: !Word8
    -- ^ days in the month (range 1-31)
  , _utcTime_hours :: !Word8
    -- ^ hours of day (range 0-23)
  , _utcTime_minutes :: !Word8
    -- ^ minutes of hour (range 0-59)
  , _utcTime_seconds :: !Word8
    -- ^ seconds of minute (range 0-60) rounded down
  , _utcTime_ns    :: !Word32
    -- ^ nanoseconds of second (range 0-999999999)
  } deriving ( Show, Read, Eq )

instance Binary UtcTime where
  get = do
    _utcTime_year <- getWord16le
    _utcTime_month <- getWord8
    _utcTime_day <- getWord8
    _utcTime_hours <- getWord8
    _utcTime_minutes <- getWord8
    _utcTime_seconds <- getWord8
    _utcTime_ns <- getWord32le
    pure UtcTime {..}

  put UtcTime {..} = do
    putWord16le _utcTime_year
    putWord8 _utcTime_month
    putWord8 _utcTime_day
    putWord8 _utcTime_hours
    putWord8 _utcTime_minutes
    putWord8 _utcTime_seconds
    putWord32le _utcTime_ns

$(makeJSON "_utcTime_" ''UtcTime)
$(makeLenses ''UtcTime)

data ECDSASignature = ECDSASignature
  { _eCDSASignature_len :: !Word8
    -- ^ Number of bytes to use of the signature field.  The DER encoded
    -- signature has a maximum size of 72 bytes but can vary between 70 and 72
    -- bytes in length.
  , _eCDSASignature_data :: ![Word8]
    -- ^ DER encoded ECDSA signature for the messages using SHA-256 as the
    -- digest algorithm.
  } deriving ( Show, Read, Eq )

instance Binary ECDSASignature where
  get = do
    _eCDSASignature_len <- getWord8
    _eCDSASignature_data <- replicateM 72 getWord8
    pure ECDSASignature {..}

  put ECDSASignature {..} = do
    putWord8 _eCDSASignature_len
    mapM_ putWord8 _eCDSASignature_data

$(makeJSON "_eCDSASignature_" ''ECDSASignature)
$(makeLenses ''ECDSASignature)

msgEcdsaCertificate :: Word16
msgEcdsaCertificate = 0x0C04

-- | SBP class for message MSG_ECDSA_CERTIFICATE (0x0C04).
--
-- A DER encoded x.509 ECDSA-256 certificate (using curve secp256r1).
data MsgEcdsaCertificate = MsgEcdsaCertificate
  { _msgEcdsaCertificate_n_msg           :: !Word8
    -- ^ Total number messages that make up the certificate. The first nibble
    -- (mask 0xF0 or left shifted by 4 bits) is the size of the sequence (n),
    -- second nibble (mask 0x0F) is the zero-indexed counter (ith packet of
    -- n).
  , _msgEcdsaCertificate_certificate_id  :: ![Word8]
    -- ^ The last 4 bytes of the certificate's SHA-1 fingerprint
  , _msgEcdsaCertificate_flags           :: !Word8
  , _msgEcdsaCertificate_certificate_bytes :: ![Word8]
    -- ^ DER encoded x.509 ECDSA certificate bytes
  } deriving ( Show, Read, Eq )

instance Binary MsgEcdsaCertificate where
  get = do
    _msgEcdsaCertificate_n_msg <- getWord8
    _msgEcdsaCertificate_certificate_id <- replicateM 4 getWord8
    _msgEcdsaCertificate_flags <- getWord8
    _msgEcdsaCertificate_certificate_bytes <- whileM (not <$> isEmpty) getWord8
    pure MsgEcdsaCertificate {..}

  put MsgEcdsaCertificate {..} = do
    putWord8 _msgEcdsaCertificate_n_msg
    mapM_ putWord8 _msgEcdsaCertificate_certificate_id
    putWord8 _msgEcdsaCertificate_flags
    mapM_ putWord8 _msgEcdsaCertificate_certificate_bytes

$(makeSBP 'msgEcdsaCertificate ''MsgEcdsaCertificate)
$(makeJSON "_msgEcdsaCertificate_" ''MsgEcdsaCertificate)
$(makeLenses ''MsgEcdsaCertificate)

msgCertificateChain :: Word16
msgCertificateChain = 0x0C09

data MsgCertificateChain = MsgCertificateChain
  { _msgCertificateChain_root_certificate       :: ![Word8]
    -- ^ SHA-1 fingerprint of the root certificate
  , _msgCertificateChain_intermediate_certificate :: ![Word8]
    -- ^ SHA-1 fingerprint of the intermediate certificate
  , _msgCertificateChain_corrections_certificate :: ![Word8]
    -- ^ SHA-1 fingerprint of the corrections certificate
  , _msgCertificateChain_expiration             :: !UtcTime
    -- ^ The time after which the signature given is no longer valid.
    -- Implementors should consult a time source (such as GNSS) to check if
    -- the current time is later than the expiration time, if the condition is
    -- true, signatures in the stream should not be considered valid.
  , _msgCertificateChain_signature              :: !ECDSASignature
    -- ^ Signature (created by the root certificate) over the concatenation of
    -- the SBP payload bytes preceding this field. That is, the concatenation
    -- of `root_certificate`, `intermediate_certificate`,
    -- `corrections_certificate` and `expiration`.  This certificate chain
    -- (allow list) can also be validated by fetching it from
    -- `http(s)://certs.swiftnav.com/chain`.
  } deriving ( Show, Read, Eq )

instance Binary MsgCertificateChain where
  get = do
    _msgCertificateChain_root_certificate <- replicateM 20 getWord8
    _msgCertificateChain_intermediate_certificate <- replicateM 20 getWord8
    _msgCertificateChain_corrections_certificate <- replicateM 20 getWord8
    _msgCertificateChain_expiration <- get
    _msgCertificateChain_signature <- get
    pure MsgCertificateChain {..}

  put MsgCertificateChain {..} = do
    mapM_ putWord8 _msgCertificateChain_root_certificate
    mapM_ putWord8 _msgCertificateChain_intermediate_certificate
    mapM_ putWord8 _msgCertificateChain_corrections_certificate
    put _msgCertificateChain_expiration
    put _msgCertificateChain_signature

$(makeSBP 'msgCertificateChain ''MsgCertificateChain)
$(makeJSON "_msgCertificateChain_" ''MsgCertificateChain)
$(makeLenses ''MsgCertificateChain)

msgCertificateChainDep :: Word16
msgCertificateChainDep = 0x0C05

-- | SBP class for message MSG_CERTIFICATE_CHAIN_DEP (0x0C05).
--
-- Deprecated.
data MsgCertificateChainDep = MsgCertificateChainDep
  { _msgCertificateChainDep_root_certificate       :: ![Word8]
    -- ^ SHA-1 fingerprint of the root certificate
  , _msgCertificateChainDep_intermediate_certificate :: ![Word8]
    -- ^ SHA-1 fingerprint of the intermediate certificate
  , _msgCertificateChainDep_corrections_certificate :: ![Word8]
    -- ^ SHA-1 fingerprint of the corrections certificate
  , _msgCertificateChainDep_expiration             :: !UtcTime
    -- ^ The certificate chain comprised of three fingerprints: root
    -- certificate, intermediate certificate and corrections certificate.
  , _msgCertificateChainDep_signature              :: ![Word8]
    -- ^ An ECDSA signature (created by the root certificate) over the
    -- concatenation of the SBP payload bytes preceding this field. That is,
    -- the concatenation of `root_certificate`, `intermediate_certificate`,
    -- `corrections_certificate` and `expiration`.  This certificate chain
    -- (allow list) can also be validated by fetching it from
    -- `http(s)://certs.swiftnav.com/chain`.
  } deriving ( Show, Read, Eq )

instance Binary MsgCertificateChainDep where
  get = do
    _msgCertificateChainDep_root_certificate <- replicateM 20 getWord8
    _msgCertificateChainDep_intermediate_certificate <- replicateM 20 getWord8
    _msgCertificateChainDep_corrections_certificate <- replicateM 20 getWord8
    _msgCertificateChainDep_expiration <- get
    _msgCertificateChainDep_signature <- replicateM 64 getWord8
    pure MsgCertificateChainDep {..}

  put MsgCertificateChainDep {..} = do
    mapM_ putWord8 _msgCertificateChainDep_root_certificate
    mapM_ putWord8 _msgCertificateChainDep_intermediate_certificate
    mapM_ putWord8 _msgCertificateChainDep_corrections_certificate
    put _msgCertificateChainDep_expiration
    mapM_ putWord8 _msgCertificateChainDep_signature

$(makeSBP 'msgCertificateChainDep ''MsgCertificateChainDep)
$(makeJSON "_msgCertificateChainDep_" ''MsgCertificateChainDep)
$(makeLenses ''MsgCertificateChainDep)

msgAesCmacSignature :: Word16
msgAesCmacSignature = 0x0C10

-- | SBP class for message MSG_AES_CMAC_SIGNATURE (0x0C10).
--
-- Digital signature using AES-CMAC 128 algorithm used for data integrity.
data MsgAesCmacSignature = MsgAesCmacSignature
  { _msgAesCmacSignature_stream_counter  :: !Word8
    -- ^ Signature message counter. Zero indexed and incremented with each
    -- signature message.  The counter will not increment if this message was
    -- in response to an on demand request.  The counter will roll over after
    -- 256 messages. Upon connection, the value of the counter may not
    -- initially be zero.
  , _msgAesCmacSignature_on_demand_counter :: !Word8
    -- ^ On demand message counter. Zero indexed and incremented with each
    -- signature message sent in response to an on demand message. The counter
    -- will roll over after 256 messages.  Upon connection, the value of the
    -- counter may not initially be zero.
  , _msgAesCmacSignature_certificate_id  :: ![Word8]
    -- ^ The last 4 bytes of the certificate's SHA-1 fingerprint
  , _msgAesCmacSignature_signature       :: ![Word8]
    -- ^ Signature (CMAC tag value)
  , _msgAesCmacSignature_flags           :: !Word8
    -- ^ Describes the format of the 'signed_messages' field.
  , _msgAesCmacSignature_signed_messages :: ![Word8]
    -- ^ CRCs of the messages covered by this signature.  For Skylark, which
    -- delivers SBP messages wrapped in Swift's proprietary RTCM message,
    -- these are the 24-bit CRCs from the RTCM message framing. For SBP only
    -- streams, this will be 16-bit CRCs from the SBP framing.  See the
    -- `flags` field to determine the type of CRCs covered.
  } deriving ( Show, Read, Eq )

instance Binary MsgAesCmacSignature where
  get = do
    _msgAesCmacSignature_stream_counter <- getWord8
    _msgAesCmacSignature_on_demand_counter <- getWord8
    _msgAesCmacSignature_certificate_id <- replicateM 4 getWord8
    _msgAesCmacSignature_signature <- replicateM 16 getWord8
    _msgAesCmacSignature_flags <- getWord8
    _msgAesCmacSignature_signed_messages <- whileM (not <$> isEmpty) getWord8
    pure MsgAesCmacSignature {..}

  put MsgAesCmacSignature {..} = do
    putWord8 _msgAesCmacSignature_stream_counter
    putWord8 _msgAesCmacSignature_on_demand_counter
    mapM_ putWord8 _msgAesCmacSignature_certificate_id
    mapM_ putWord8 _msgAesCmacSignature_signature
    putWord8 _msgAesCmacSignature_flags
    mapM_ putWord8 _msgAesCmacSignature_signed_messages

$(makeSBP 'msgAesCmacSignature ''MsgAesCmacSignature)
$(makeJSON "_msgAesCmacSignature_" ''MsgAesCmacSignature)
$(makeLenses ''MsgAesCmacSignature)

msgEcdsaSignature :: Word16
msgEcdsaSignature = 0x0C08

-- | SBP class for message MSG_ECDSA_SIGNATURE (0x0C08).
--
-- An ECDSA-256 signature using SHA-256 as the message digest algorithm.
data MsgEcdsaSignature = MsgEcdsaSignature
  { _msgEcdsaSignature_flags           :: !Word8
    -- ^ Describes the format of the 'signed_messages' field.
  , _msgEcdsaSignature_stream_counter  :: !Word8
    -- ^ Signature message counter. Zero indexed and incremented with each
    -- signature message.  The counter will not increment if this message was
    -- in response to an on demand request.  The counter will roll over after
    -- 256 messages. Upon connection, the value of the counter may not
    -- initially be zero.
  , _msgEcdsaSignature_on_demand_counter :: !Word8
    -- ^ On demand message counter. Zero indexed and incremented with each
    -- signature message sent in response to an on demand message. The counter
    -- will roll over after 256 messages.  Upon connection, the value of the
    -- counter may not initially be zero.
  , _msgEcdsaSignature_certificate_id  :: ![Word8]
    -- ^ The last 4 bytes of the certificate's SHA-1 fingerprint
  , _msgEcdsaSignature_signature       :: !ECDSASignature
    -- ^ Signature over the frames of this message group.
  , _msgEcdsaSignature_signed_messages :: ![Word8]
    -- ^ CRCs of the messages covered by this signature.  For Skylark, which
    -- delivers SBP messages wrapped in Swift's proprietary RTCM message,
    -- these are the 24-bit CRCs from the RTCM message framing. For SBP only
    -- streams, this will be 16-bit CRCs from the SBP framing.  See the
    -- `flags` field to determine the type of CRCs covered.
  } deriving ( Show, Read, Eq )

instance Binary MsgEcdsaSignature where
  get = do
    _msgEcdsaSignature_flags <- getWord8
    _msgEcdsaSignature_stream_counter <- getWord8
    _msgEcdsaSignature_on_demand_counter <- getWord8
    _msgEcdsaSignature_certificate_id <- replicateM 4 getWord8
    _msgEcdsaSignature_signature <- get
    _msgEcdsaSignature_signed_messages <- whileM (not <$> isEmpty) getWord8
    pure MsgEcdsaSignature {..}

  put MsgEcdsaSignature {..} = do
    putWord8 _msgEcdsaSignature_flags
    putWord8 _msgEcdsaSignature_stream_counter
    putWord8 _msgEcdsaSignature_on_demand_counter
    mapM_ putWord8 _msgEcdsaSignature_certificate_id
    put _msgEcdsaSignature_signature
    mapM_ putWord8 _msgEcdsaSignature_signed_messages

$(makeSBP 'msgEcdsaSignature ''MsgEcdsaSignature)
$(makeJSON "_msgEcdsaSignature_" ''MsgEcdsaSignature)
$(makeLenses ''MsgEcdsaSignature)

msgEcdsaSignatureDepB :: Word16
msgEcdsaSignatureDepB = 0x0C07

-- | SBP class for message MSG_ECDSA_SIGNATURE_DEP_B (0x0C07).
--
-- Deprecated.
data MsgEcdsaSignatureDepB = MsgEcdsaSignatureDepB
  { _msgEcdsaSignatureDepB_flags           :: !Word8
    -- ^ Describes the format of the 'signed_messages' field.
  , _msgEcdsaSignatureDepB_stream_counter  :: !Word8
    -- ^ Signature message counter. Zero indexed and incremented with each
    -- signature message.  The counter will not increment if this message was
    -- in response to an on demand request.  The counter will roll over after
    -- 256 messages. Upon connection, the value of the counter may not
    -- initially be zero.
  , _msgEcdsaSignatureDepB_on_demand_counter :: !Word8
    -- ^ On demand message counter. Zero indexed and incremented with each
    -- signature message sent in response to an on demand message. The counter
    -- will roll over after 256 messages.  Upon connection, the value of the
    -- counter may not initially be zero.
  , _msgEcdsaSignatureDepB_certificate_id  :: ![Word8]
    -- ^ The last 4 bytes of the certificate's SHA-1 fingerprint
  , _msgEcdsaSignatureDepB_n_signature_bytes :: !Word8
    -- ^ Number of bytes to use of the signature field.  The DER encoded
    -- signature has a maximum size of 72 bytes but can vary between 70 and 72
    -- bytes in length.
  , _msgEcdsaSignatureDepB_signature       :: ![Word8]
    -- ^ DER encoded ECDSA signature for the messages using SHA-256 as the
    -- digest algorithm.
  , _msgEcdsaSignatureDepB_signed_messages :: ![Word8]
    -- ^ CRCs of the messages covered by this signature.  For Skylark, which
    -- delivers SBP messages wrapped in Swift's proprietary RTCM message,
    -- these are the 24-bit CRCs from the RTCM message framing. For SBP only
    -- streams, this will be 16-bit CRCs from the SBP framing.  See the
    -- `flags` field to determine the type of CRCs covered.
  } deriving ( Show, Read, Eq )

instance Binary MsgEcdsaSignatureDepB where
  get = do
    _msgEcdsaSignatureDepB_flags <- getWord8
    _msgEcdsaSignatureDepB_stream_counter <- getWord8
    _msgEcdsaSignatureDepB_on_demand_counter <- getWord8
    _msgEcdsaSignatureDepB_certificate_id <- replicateM 4 getWord8
    _msgEcdsaSignatureDepB_n_signature_bytes <- getWord8
    _msgEcdsaSignatureDepB_signature <- replicateM 72 getWord8
    _msgEcdsaSignatureDepB_signed_messages <- whileM (not <$> isEmpty) getWord8
    pure MsgEcdsaSignatureDepB {..}

  put MsgEcdsaSignatureDepB {..} = do
    putWord8 _msgEcdsaSignatureDepB_flags
    putWord8 _msgEcdsaSignatureDepB_stream_counter
    putWord8 _msgEcdsaSignatureDepB_on_demand_counter
    mapM_ putWord8 _msgEcdsaSignatureDepB_certificate_id
    putWord8 _msgEcdsaSignatureDepB_n_signature_bytes
    mapM_ putWord8 _msgEcdsaSignatureDepB_signature
    mapM_ putWord8 _msgEcdsaSignatureDepB_signed_messages

$(makeSBP 'msgEcdsaSignatureDepB ''MsgEcdsaSignatureDepB)
$(makeJSON "_msgEcdsaSignatureDepB_" ''MsgEcdsaSignatureDepB)
$(makeLenses ''MsgEcdsaSignatureDepB)

msgEcdsaSignatureDepA :: Word16
msgEcdsaSignatureDepA = 0x0C06

-- | SBP class for message MSG_ECDSA_SIGNATURE_DEP_A (0x0C06).
--
-- Deprecated.
data MsgEcdsaSignatureDepA = MsgEcdsaSignatureDepA
  { _msgEcdsaSignatureDepA_flags           :: !Word8
    -- ^ Describes the format of the 'signed_messages' field.
  , _msgEcdsaSignatureDepA_stream_counter  :: !Word8
    -- ^ Signature message counter. Zero indexed and incremented with each
    -- signature message.  The counter will not increment if this message was
    -- in response to an on demand request.  The counter will roll over after
    -- 256 messages. Upon connection, the value of the counter may not
    -- initially be zero.
  , _msgEcdsaSignatureDepA_on_demand_counter :: !Word8
    -- ^ On demand message counter. Zero indexed and incremented with each
    -- signature message sent in response to an on demand message. The counter
    -- will roll over after 256 messages.  Upon connection, the value of the
    -- counter may not initially be zero.
  , _msgEcdsaSignatureDepA_certificate_id  :: ![Word8]
    -- ^ The last 4 bytes of the certificate's SHA-1 fingerprint
  , _msgEcdsaSignatureDepA_signature       :: ![Word8]
    -- ^ ECDSA signature for the messages using SHA-256 as the digest algorithm.
  , _msgEcdsaSignatureDepA_signed_messages :: ![Word8]
    -- ^ CRCs of the messages covered by this signature.  For Skylark, which
    -- delivers SBP messages wrapped in Swift's proprietary RTCM message,
    -- these are the 24-bit CRCs from the RTCM message framing. For SBP only
    -- streams, this will be 16-bit CRCs from the SBP framing.  See the
    -- `flags` field to determine the type of CRCs covered.
  } deriving ( Show, Read, Eq )

instance Binary MsgEcdsaSignatureDepA where
  get = do
    _msgEcdsaSignatureDepA_flags <- getWord8
    _msgEcdsaSignatureDepA_stream_counter <- getWord8
    _msgEcdsaSignatureDepA_on_demand_counter <- getWord8
    _msgEcdsaSignatureDepA_certificate_id <- replicateM 4 getWord8
    _msgEcdsaSignatureDepA_signature <- replicateM 64 getWord8
    _msgEcdsaSignatureDepA_signed_messages <- whileM (not <$> isEmpty) getWord8
    pure MsgEcdsaSignatureDepA {..}

  put MsgEcdsaSignatureDepA {..} = do
    putWord8 _msgEcdsaSignatureDepA_flags
    putWord8 _msgEcdsaSignatureDepA_stream_counter
    putWord8 _msgEcdsaSignatureDepA_on_demand_counter
    mapM_ putWord8 _msgEcdsaSignatureDepA_certificate_id
    mapM_ putWord8 _msgEcdsaSignatureDepA_signature
    mapM_ putWord8 _msgEcdsaSignatureDepA_signed_messages

$(makeSBP 'msgEcdsaSignatureDepA ''MsgEcdsaSignatureDepA)
$(makeJSON "_msgEcdsaSignatureDepA_" ''MsgEcdsaSignatureDepA)
$(makeLenses ''MsgEcdsaSignatureDepA)

msgEd25519CertificateDep :: Word16
msgEd25519CertificateDep = 0x0C02

-- | SBP class for message MSG_ED25519_CERTIFICATE_DEP (0x0C02).
--
-- Deprecated.
data MsgEd25519CertificateDep = MsgEd25519CertificateDep
  { _msgEd25519CertificateDep_n_msg           :: !Word8
    -- ^ Total number messages that make up the certificate. First nibble is the
    -- size of the sequence (n), second nibble is the zero-indexed counter
    -- (ith packet of n)
  , _msgEd25519CertificateDep_fingerprint     :: ![Word8]
    -- ^ SHA-1 fingerprint of the associated certificate.
  , _msgEd25519CertificateDep_certificate_bytes :: ![Word8]
    -- ^ ED25519 certificate bytes.
  } deriving ( Show, Read, Eq )

instance Binary MsgEd25519CertificateDep where
  get = do
    _msgEd25519CertificateDep_n_msg <- getWord8
    _msgEd25519CertificateDep_fingerprint <- replicateM 20 getWord8
    _msgEd25519CertificateDep_certificate_bytes <- whileM (not <$> isEmpty) getWord8
    pure MsgEd25519CertificateDep {..}

  put MsgEd25519CertificateDep {..} = do
    putWord8 _msgEd25519CertificateDep_n_msg
    mapM_ putWord8 _msgEd25519CertificateDep_fingerprint
    mapM_ putWord8 _msgEd25519CertificateDep_certificate_bytes

$(makeSBP 'msgEd25519CertificateDep ''MsgEd25519CertificateDep)
$(makeJSON "_msgEd25519CertificateDep_" ''MsgEd25519CertificateDep)
$(makeLenses ''MsgEd25519CertificateDep)

msgEd25519SignatureDepA :: Word16
msgEd25519SignatureDepA = 0x0C01

-- | SBP class for message MSG_ED25519_SIGNATURE_DEP_A (0x0C01).
--
-- Deprecated.
data MsgEd25519SignatureDepA = MsgEd25519SignatureDepA
  { _msgEd25519SignatureDepA_signature     :: ![Word8]
    -- ^ ED25519 signature for messages.
  , _msgEd25519SignatureDepA_fingerprint   :: ![Word8]
    -- ^ SHA-1 fingerprint of the associated certificate.
  , _msgEd25519SignatureDepA_signed_messages :: ![Word32]
    -- ^ CRCs of signed messages.
  } deriving ( Show, Read, Eq )

instance Binary MsgEd25519SignatureDepA where
  get = do
    _msgEd25519SignatureDepA_signature <- replicateM 64 getWord8
    _msgEd25519SignatureDepA_fingerprint <- replicateM 20 getWord8
    _msgEd25519SignatureDepA_signed_messages <- whileM (not <$> isEmpty) getWord32le
    pure MsgEd25519SignatureDepA {..}

  put MsgEd25519SignatureDepA {..} = do
    mapM_ putWord8 _msgEd25519SignatureDepA_signature
    mapM_ putWord8 _msgEd25519SignatureDepA_fingerprint
    mapM_ putWord32le _msgEd25519SignatureDepA_signed_messages

$(makeSBP 'msgEd25519SignatureDepA ''MsgEd25519SignatureDepA)
$(makeJSON "_msgEd25519SignatureDepA_" ''MsgEd25519SignatureDepA)
$(makeLenses ''MsgEd25519SignatureDepA)

msgEd25519SignatureDepB :: Word16
msgEd25519SignatureDepB = 0x0C03

-- | SBP class for message MSG_ED25519_SIGNATURE_DEP_B (0x0C03).
--
-- Deprecated.
data MsgEd25519SignatureDepB = MsgEd25519SignatureDepB
  { _msgEd25519SignatureDepB_stream_counter  :: !Word8
    -- ^ Signature message counter. Zero indexed and incremented with each
    -- signature message.  The counter will not increment if this message was
    -- in response to an on demand request.  The counter will roll over after
    -- 256 messages. Upon connection, the value of the counter may not
    -- initially be zero.
  , _msgEd25519SignatureDepB_on_demand_counter :: !Word8
    -- ^ On demand message counter. Zero indexed and incremented with each
    -- signature message sent in response to an on demand message. The counter
    -- will roll over after 256 messages.  Upon connection, the value of the
    -- counter may not initially be zero.
  , _msgEd25519SignatureDepB_signature       :: ![Word8]
    -- ^ ED25519 signature for messages.
  , _msgEd25519SignatureDepB_fingerprint     :: ![Word8]
    -- ^ SHA-1 fingerprint of the associated certificate.
  , _msgEd25519SignatureDepB_signed_messages :: ![Word32]
    -- ^ CRCs of signed messages.
  } deriving ( Show, Read, Eq )

instance Binary MsgEd25519SignatureDepB where
  get = do
    _msgEd25519SignatureDepB_stream_counter <- getWord8
    _msgEd25519SignatureDepB_on_demand_counter <- getWord8
    _msgEd25519SignatureDepB_signature <- replicateM 64 getWord8
    _msgEd25519SignatureDepB_fingerprint <- replicateM 20 getWord8
    _msgEd25519SignatureDepB_signed_messages <- whileM (not <$> isEmpty) getWord32le
    pure MsgEd25519SignatureDepB {..}

  put MsgEd25519SignatureDepB {..} = do
    putWord8 _msgEd25519SignatureDepB_stream_counter
    putWord8 _msgEd25519SignatureDepB_on_demand_counter
    mapM_ putWord8 _msgEd25519SignatureDepB_signature
    mapM_ putWord8 _msgEd25519SignatureDepB_fingerprint
    mapM_ putWord32le _msgEd25519SignatureDepB_signed_messages

$(makeSBP 'msgEd25519SignatureDepB ''MsgEd25519SignatureDepB)
$(makeJSON "_msgEd25519SignatureDepB_" ''MsgEd25519SignatureDepB)
$(makeLenses ''MsgEd25519SignatureDepB)