{-# LANGUAGE NoImplicitPrelude #-}

-- |
-- Module:      SwiftNav.SBP
-- Copyright:   Copyright (C) 2015-2021 Swift Navigation, Inc.
-- License:     MIT
-- Contact:     https://support.swiftnav.com
-- Stability:   experimental
-- Portability: portable
--
-- Error detection functions.

module SwiftNav.CRC16
  ( crc16
  ) where

import BasicPrelude         hiding (ByteString, foldl')
import Data.Array
import Data.Bits
import Data.ByteString.Lazy
import Data.Word

table :: Array Word16 Word16
table :: Array Word16 Word16
table = (Word16, Word16) -> [Word16] -> Array Word16 Word16
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Word16
0, Word16
255)
  [ Word16
0x0000, Word16
0x1021, Word16
0x2042, Word16
0x3063, Word16
0x4084, Word16
0x50a5, Word16
0x60c6, Word16
0x70e7
  , Word16
0x8108, Word16
0x9129, Word16
0xa14a, Word16
0xb16b, Word16
0xc18c, Word16
0xd1ad, Word16
0xe1ce, Word16
0xf1ef
  , Word16
0x1231, Word16
0x0210, Word16
0x3273, Word16
0x2252, Word16
0x52b5, Word16
0x4294, Word16
0x72f7, Word16
0x62d6
  , Word16
0x9339, Word16
0x8318, Word16
0xb37b, Word16
0xa35a, Word16
0xd3bd, Word16
0xc39c, Word16
0xf3ff, Word16
0xe3de
  , Word16
0x2462, Word16
0x3443, Word16
0x0420, Word16
0x1401, Word16
0x64e6, Word16
0x74c7, Word16
0x44a4, Word16
0x5485
  , Word16
0xa56a, Word16
0xb54b, Word16
0x8528, Word16
0x9509, Word16
0xe5ee, Word16
0xf5cf, Word16
0xc5ac, Word16
0xd58d
  , Word16
0x3653, Word16
0x2672, Word16
0x1611, Word16
0x0630, Word16
0x76d7, Word16
0x66f6, Word16
0x5695, Word16
0x46b4
  , Word16
0xb75b, Word16
0xa77a, Word16
0x9719, Word16
0x8738, Word16
0xf7df, Word16
0xe7fe, Word16
0xd79d, Word16
0xc7bc
  , Word16
0x48c4, Word16
0x58e5, Word16
0x6886, Word16
0x78a7, Word16
0x0840, Word16
0x1861, Word16
0x2802, Word16
0x3823
  , Word16
0xc9cc, Word16
0xd9ed, Word16
0xe98e, Word16
0xf9af, Word16
0x8948, Word16
0x9969, Word16
0xa90a, Word16
0xb92b
  , Word16
0x5af5, Word16
0x4ad4, Word16
0x7ab7, Word16
0x6a96, Word16
0x1a71, Word16
0x0a50, Word16
0x3a33, Word16
0x2a12
  , Word16
0xdbfd, Word16
0xcbdc, Word16
0xfbbf, Word16
0xeb9e, Word16
0x9b79, Word16
0x8b58, Word16
0xbb3b, Word16
0xab1a
  , Word16
0x6ca6, Word16
0x7c87, Word16
0x4ce4, Word16
0x5cc5, Word16
0x2c22, Word16
0x3c03, Word16
0x0c60, Word16
0x1c41
  , Word16
0xedae, Word16
0xfd8f, Word16
0xcdec, Word16
0xddcd, Word16
0xad2a, Word16
0xbd0b, Word16
0x8d68, Word16
0x9d49
  , Word16
0x7e97, Word16
0x6eb6, Word16
0x5ed5, Word16
0x4ef4, Word16
0x3e13, Word16
0x2e32, Word16
0x1e51, Word16
0x0e70
  , Word16
0xff9f, Word16
0xefbe, Word16
0xdfdd, Word16
0xcffc, Word16
0xbf1b, Word16
0xaf3a, Word16
0x9f59, Word16
0x8f78
  , Word16
0x9188, Word16
0x81a9, Word16
0xb1ca, Word16
0xa1eb, Word16
0xd10c, Word16
0xc12d, Word16
0xf14e, Word16
0xe16f
  , Word16
0x1080, Word16
0x00a1, Word16
0x30c2, Word16
0x20e3, Word16
0x5004, Word16
0x4025, Word16
0x7046, Word16
0x6067
  , Word16
0x83b9, Word16
0x9398, Word16
0xa3fb, Word16
0xb3da, Word16
0xc33d, Word16
0xd31c, Word16
0xe37f, Word16
0xf35e
  , Word16
0x02b1, Word16
0x1290, Word16
0x22f3, Word16
0x32d2, Word16
0x4235, Word16
0x5214, Word16
0x6277, Word16
0x7256
  , Word16
0xb5ea, Word16
0xa5cb, Word16
0x95a8, Word16
0x8589, Word16
0xf56e, Word16
0xe54f, Word16
0xd52c, Word16
0xc50d
  , Word16
0x34e2, Word16
0x24c3, Word16
0x14a0, Word16
0x0481, Word16
0x7466, Word16
0x6447, Word16
0x5424, Word16
0x4405
  , Word16
0xa7db, Word16
0xb7fa, Word16
0x8799, Word16
0x97b8, Word16
0xe75f, Word16
0xf77e, Word16
0xc71d, Word16
0xd73c
  , Word16
0x26d3, Word16
0x36f2, Word16
0x0691, Word16
0x16b0, Word16
0x6657, Word16
0x7676, Word16
0x4615, Word16
0x5634
  , Word16
0xd94c, Word16
0xc96d, Word16
0xf90e, Word16
0xe92f, Word16
0x99c8, Word16
0x89e9, Word16
0xb98a, Word16
0xa9ab
  , Word16
0x5844, Word16
0x4865, Word16
0x7806, Word16
0x6827, Word16
0x18c0, Word16
0x08e1, Word16
0x3882, Word16
0x28a3
  , Word16
0xcb7d, Word16
0xdb5c, Word16
0xeb3f, Word16
0xfb1e, Word16
0x8bf9, Word16
0x9bd8, Word16
0xabbb, Word16
0xbb9a
  , Word16
0x4a75, Word16
0x5a54, Word16
0x6a37, Word16
0x7a16, Word16
0x0af1, Word16
0x1ad0, Word16
0x2ab3, Word16
0x3a92
  , Word16
0xfd2e, Word16
0xed0f, Word16
0xdd6c, Word16
0xcd4d, Word16
0xbdaa, Word16
0xad8b, Word16
0x9de8, Word16
0x8dc9
  , Word16
0x7c26, Word16
0x6c07, Word16
0x5c64, Word16
0x4c45, Word16
0x3ca2, Word16
0x2c83, Word16
0x1ce0, Word16
0x0cc1
  , Word16
0xef1f, Word16
0xff3e, Word16
0xcf5d, Word16
0xdf7c, Word16
0xaf9b, Word16
0xbfba, Word16
0x8fd9, Word16
0x9ff8
  , Word16
0x6e17, Word16
0x7e36, Word16
0x4e55, Word16
0x5e74, Word16
0x2e93, Word16
0x3eb2, Word16
0x0ed1, Word16
0x1ef0
  ]

-- | Calculate CCITT 16-bit Cyclical Redundancy Check (CRC16).
crc16 :: ByteString -> Word16
crc16 :: ByteString -> Word16
crc16 =
  (Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xffff) (Word16 -> Word16)
-> (ByteString -> Word16) -> ByteString -> Word16
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Word16 -> Word8 -> Word16) -> Word16 -> ByteString -> Word16
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' Word16 -> Word8 -> Word16
forall a. Integral a => Word16 -> a -> Word16
f Word16
0 where
    f :: Word16 -> a -> Word16
f Word16
ac a
v = ((Word16
ac Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xff00) Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
`xor` (Array Word16 Word16
table Array Word16 Word16 -> Word16 -> Word16
forall i e. Ix i => Array i e -> i -> e
! Word16
idx) where
      idx :: Word16
idx = ((Word16
ac Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftR` Int
8) Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xff) Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
`xor` a -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
v