{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RecordWildCards #-}
module Network.NTP.Client.Packet
( NtpPacket (..)
, ntpPacketSize
, mkNtpPacket
, NtpOffset (..)
, getCurrentTime
, clockOffsetPure
, clockOffset
, realMcsToNtp
, ntpToRealMcs
, Microsecond (..)
) where
import Control.Monad (replicateM_)
import Data.Binary (Binary (..))
import Data.Binary.Get (getInt8, getWord32be, getWord8, skip)
import Data.Binary.Put (putInt8, putWord32be, putWord8)
import Data.Int (Int8)
import Data.Time.Clock.POSIX (getPOSIXTime)
import Data.Word (Word32, Word8)
newtype Microsecond = Microsecond Integer
deriving (Int -> Microsecond
Microsecond -> Int
Microsecond -> [Microsecond]
Microsecond -> Microsecond
Microsecond -> Microsecond -> [Microsecond]
Microsecond -> Microsecond -> Microsecond -> [Microsecond]
(Microsecond -> Microsecond)
-> (Microsecond -> Microsecond)
-> (Int -> Microsecond)
-> (Microsecond -> Int)
-> (Microsecond -> [Microsecond])
-> (Microsecond -> Microsecond -> [Microsecond])
-> (Microsecond -> Microsecond -> [Microsecond])
-> (Microsecond -> Microsecond -> Microsecond -> [Microsecond])
-> Enum Microsecond
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Microsecond -> Microsecond
succ :: Microsecond -> Microsecond
$cpred :: Microsecond -> Microsecond
pred :: Microsecond -> Microsecond
$ctoEnum :: Int -> Microsecond
toEnum :: Int -> Microsecond
$cfromEnum :: Microsecond -> Int
fromEnum :: Microsecond -> Int
$cenumFrom :: Microsecond -> [Microsecond]
enumFrom :: Microsecond -> [Microsecond]
$cenumFromThen :: Microsecond -> Microsecond -> [Microsecond]
enumFromThen :: Microsecond -> Microsecond -> [Microsecond]
$cenumFromTo :: Microsecond -> Microsecond -> [Microsecond]
enumFromTo :: Microsecond -> Microsecond -> [Microsecond]
$cenumFromThenTo :: Microsecond -> Microsecond -> Microsecond -> [Microsecond]
enumFromThenTo :: Microsecond -> Microsecond -> Microsecond -> [Microsecond]
Enum, Microsecond -> Microsecond -> Bool
(Microsecond -> Microsecond -> Bool)
-> (Microsecond -> Microsecond -> Bool) -> Eq Microsecond
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Microsecond -> Microsecond -> Bool
== :: Microsecond -> Microsecond -> Bool
$c/= :: Microsecond -> Microsecond -> Bool
/= :: Microsecond -> Microsecond -> Bool
Eq, Integer -> Microsecond
Microsecond -> Microsecond
Microsecond -> Microsecond -> Microsecond
(Microsecond -> Microsecond -> Microsecond)
-> (Microsecond -> Microsecond -> Microsecond)
-> (Microsecond -> Microsecond -> Microsecond)
-> (Microsecond -> Microsecond)
-> (Microsecond -> Microsecond)
-> (Microsecond -> Microsecond)
-> (Integer -> Microsecond)
-> Num Microsecond
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Microsecond -> Microsecond -> Microsecond
+ :: Microsecond -> Microsecond -> Microsecond
$c- :: Microsecond -> Microsecond -> Microsecond
- :: Microsecond -> Microsecond -> Microsecond
$c* :: Microsecond -> Microsecond -> Microsecond
* :: Microsecond -> Microsecond -> Microsecond
$cnegate :: Microsecond -> Microsecond
negate :: Microsecond -> Microsecond
$cabs :: Microsecond -> Microsecond
abs :: Microsecond -> Microsecond
$csignum :: Microsecond -> Microsecond
signum :: Microsecond -> Microsecond
$cfromInteger :: Integer -> Microsecond
fromInteger :: Integer -> Microsecond
Num, Eq Microsecond
Eq Microsecond =>
(Microsecond -> Microsecond -> Ordering)
-> (Microsecond -> Microsecond -> Bool)
-> (Microsecond -> Microsecond -> Bool)
-> (Microsecond -> Microsecond -> Bool)
-> (Microsecond -> Microsecond -> Bool)
-> (Microsecond -> Microsecond -> Microsecond)
-> (Microsecond -> Microsecond -> Microsecond)
-> Ord Microsecond
Microsecond -> Microsecond -> Bool
Microsecond -> Microsecond -> Ordering
Microsecond -> Microsecond -> Microsecond
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Microsecond -> Microsecond -> Ordering
compare :: Microsecond -> Microsecond -> Ordering
$c< :: Microsecond -> Microsecond -> Bool
< :: Microsecond -> Microsecond -> Bool
$c<= :: Microsecond -> Microsecond -> Bool
<= :: Microsecond -> Microsecond -> Bool
$c> :: Microsecond -> Microsecond -> Bool
> :: Microsecond -> Microsecond -> Bool
$c>= :: Microsecond -> Microsecond -> Bool
>= :: Microsecond -> Microsecond -> Bool
$cmax :: Microsecond -> Microsecond -> Microsecond
max :: Microsecond -> Microsecond -> Microsecond
$cmin :: Microsecond -> Microsecond -> Microsecond
min :: Microsecond -> Microsecond -> Microsecond
Ord, Num Microsecond
Ord Microsecond
(Num Microsecond, Ord Microsecond) =>
(Microsecond -> Rational) -> Real Microsecond
Microsecond -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: Microsecond -> Rational
toRational :: Microsecond -> Rational
Real, Int -> Microsecond -> ShowS
[Microsecond] -> ShowS
Microsecond -> String
(Int -> Microsecond -> ShowS)
-> (Microsecond -> String)
-> ([Microsecond] -> ShowS)
-> Show Microsecond
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Microsecond -> ShowS
showsPrec :: Int -> Microsecond -> ShowS
$cshow :: Microsecond -> String
show :: Microsecond -> String
$cshowList :: [Microsecond] -> ShowS
showList :: [Microsecond] -> ShowS
Show)
instance Integral Microsecond where
toInteger :: Microsecond -> Integer
toInteger (Microsecond Integer
a) = Integer
a
(Microsecond Integer
a) quotRem :: Microsecond -> Microsecond -> (Microsecond, Microsecond)
`quotRem` (Microsecond Integer
b) =
case Integer
a Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Integer
b of
(Integer
x, Integer
r) -> (Integer -> Microsecond
Microsecond Integer
x, Integer -> Microsecond
Microsecond Integer
r)
data NtpPacket = NtpPacket
{ NtpPacket -> Word8
ntpParams :: Word8
, NtpPacket -> Int8
ntpPoll :: Int8
, NtpPacket -> Microsecond
ntpOriginTime :: Microsecond
, NtpPacket -> Microsecond
ntpReceivedTime :: Microsecond
, NtpPacket -> Microsecond
ntpTransmitTime :: Microsecond
} deriving (Int -> NtpPacket -> ShowS
[NtpPacket] -> ShowS
NtpPacket -> String
(Int -> NtpPacket -> ShowS)
-> (NtpPacket -> String)
-> ([NtpPacket] -> ShowS)
-> Show NtpPacket
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NtpPacket -> ShowS
showsPrec :: Int -> NtpPacket -> ShowS
$cshow :: NtpPacket -> String
show :: NtpPacket -> String
$cshowList :: [NtpPacket] -> ShowS
showList :: [NtpPacket] -> ShowS
Show, NtpPacket -> NtpPacket -> Bool
(NtpPacket -> NtpPacket -> Bool)
-> (NtpPacket -> NtpPacket -> Bool) -> Eq NtpPacket
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NtpPacket -> NtpPacket -> Bool
== :: NtpPacket -> NtpPacket -> Bool
$c/= :: NtpPacket -> NtpPacket -> Bool
/= :: NtpPacket -> NtpPacket -> Bool
Eq)
instance Binary NtpPacket where
put :: NtpPacket -> Put
put NtpPacket{Int8
Word8
Microsecond
ntpParams :: NtpPacket -> Word8
ntpPoll :: NtpPacket -> Int8
ntpOriginTime :: NtpPacket -> Microsecond
ntpReceivedTime :: NtpPacket -> Microsecond
ntpTransmitTime :: NtpPacket -> Microsecond
ntpParams :: Word8
ntpPoll :: Int8
ntpOriginTime :: Microsecond
ntpReceivedTime :: Microsecond
ntpTransmitTime :: Microsecond
..} = do
Word8 -> Put
putWord8 Word8
ntpParams
Word8 -> Put
putWord8 Word8
0
Int8 -> Put
putInt8 Int8
ntpPoll
Word8 -> Put
putWord8 Word8
0
Int -> Put -> Put
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
5 (Put -> Put) -> Put -> Put
forall a b. (a -> b) -> a -> b
$ Word32 -> Put
putWord32be Word32
0
let (Word32
osec, Word32
ofrac) = Microsecond -> (Word32, Word32)
realMcsToNtp Microsecond
ntpOriginTime
Word32 -> Put
putWord32be Word32
osec
Word32 -> Put
putWord32be Word32
ofrac
let (Word32
rsec, Word32
rfrac) = Microsecond -> (Word32, Word32)
realMcsToNtp Microsecond
ntpReceivedTime
Word32 -> Put
putWord32be Word32
rsec
Word32 -> Put
putWord32be Word32
rfrac
let (Word32
tsec, Word32
tfrac) = Microsecond -> (Word32, Word32)
realMcsToNtp Microsecond
ntpTransmitTime
Word32 -> Put
putWord32be Word32
tsec
Word32 -> Put
putWord32be Word32
tfrac
get :: Get NtpPacket
get = do
ntpParams <- Get Word8
getWord8
_ <- getWord8
ntpPoll <- getInt8
_ <- getWord8
skip 20
ntpOriginTime <- getTimestamp
ntpReceivedTime <- getTimestamp
ntpTransmitTime <- getTimestamp
return NtpPacket{..}
where
getTimestamp :: Get Microsecond
getTimestamp = Word32 -> Word32 -> Microsecond
ntpToRealMcs (Word32 -> Word32 -> Microsecond)
-> Get Word32 -> Get (Word32 -> Microsecond)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32be Get (Word32 -> Microsecond) -> Get Word32 -> Get Microsecond
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word32
getWord32be
ntpTimestampDelta :: Integer
ntpTimestampDelta :: Integer
ntpTimestampDelta = Integer
2208988800
ntpPacketSize :: Int
ntpPacketSize :: Int
ntpPacketSize = Int
48
ntpToRealMcs :: Word32 -> Word32 -> Microsecond
ntpToRealMcs :: Word32 -> Word32 -> Microsecond
ntpToRealMcs Word32
sec Word32
frac =
let
secMicro :: Integer
secMicro :: Integer
secMicro = (Word32 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
sec Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
ntpTimestampDelta) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000000
fracMicro :: Integer
fracMicro :: Integer
fracMicro = (Word32 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
frac) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
4294
in Integer -> Microsecond
Microsecond (Integer -> Microsecond) -> Integer -> Microsecond
forall a b. (a -> b) -> a -> b
$ Integer
secMicro Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
fracMicro
realMcsToNtp :: Microsecond -> (Word32, Word32)
realMcsToNtp :: Microsecond -> (Word32, Word32)
realMcsToNtp (Microsecond Integer
mcs) =
let (Integer
sec, Integer
frac) = Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
divMod Integer
mcs Integer
1000000
in ( Integer -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Word32) -> Integer -> Word32
forall a b. (a -> b) -> a -> b
$ Integer
sec Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
ntpTimestampDelta
, Integer -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Word32) -> Integer -> Word32
forall a b. (a -> b) -> a -> b
$ Integer
frac Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
4294)
mkNtpPacket :: IO NtpPacket
mkNtpPacket :: IO NtpPacket
mkNtpPacket = do
let ntpParams :: Word8
ntpParams = Word8
0x1b
ntpPoll :: Int8
ntpPoll = Int8
0
ntpOriginTime :: Microsecond
ntpOriginTime = Microsecond
0
ntpReceivedTime :: Microsecond
ntpReceivedTime = Microsecond
0
ntpTransmitTime <- IO Microsecond
getCurrentTime
return NtpPacket{..}
newtype NtpOffset = NtpOffset { NtpOffset -> Microsecond
getNtpOffset :: Microsecond }
deriving (Int -> NtpOffset
NtpOffset -> Int
NtpOffset -> [NtpOffset]
NtpOffset -> NtpOffset
NtpOffset -> NtpOffset -> [NtpOffset]
NtpOffset -> NtpOffset -> NtpOffset -> [NtpOffset]
(NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset)
-> (Int -> NtpOffset)
-> (NtpOffset -> Int)
-> (NtpOffset -> [NtpOffset])
-> (NtpOffset -> NtpOffset -> [NtpOffset])
-> (NtpOffset -> NtpOffset -> [NtpOffset])
-> (NtpOffset -> NtpOffset -> NtpOffset -> [NtpOffset])
-> Enum NtpOffset
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: NtpOffset -> NtpOffset
succ :: NtpOffset -> NtpOffset
$cpred :: NtpOffset -> NtpOffset
pred :: NtpOffset -> NtpOffset
$ctoEnum :: Int -> NtpOffset
toEnum :: Int -> NtpOffset
$cfromEnum :: NtpOffset -> Int
fromEnum :: NtpOffset -> Int
$cenumFrom :: NtpOffset -> [NtpOffset]
enumFrom :: NtpOffset -> [NtpOffset]
$cenumFromThen :: NtpOffset -> NtpOffset -> [NtpOffset]
enumFromThen :: NtpOffset -> NtpOffset -> [NtpOffset]
$cenumFromTo :: NtpOffset -> NtpOffset -> [NtpOffset]
enumFromTo :: NtpOffset -> NtpOffset -> [NtpOffset]
$cenumFromThenTo :: NtpOffset -> NtpOffset -> NtpOffset -> [NtpOffset]
enumFromThenTo :: NtpOffset -> NtpOffset -> NtpOffset -> [NtpOffset]
Enum, NtpOffset -> NtpOffset -> Bool
(NtpOffset -> NtpOffset -> Bool)
-> (NtpOffset -> NtpOffset -> Bool) -> Eq NtpOffset
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NtpOffset -> NtpOffset -> Bool
== :: NtpOffset -> NtpOffset -> Bool
$c/= :: NtpOffset -> NtpOffset -> Bool
/= :: NtpOffset -> NtpOffset -> Bool
Eq, Enum NtpOffset
Real NtpOffset
(Real NtpOffset, Enum NtpOffset) =>
(NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset))
-> (NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset))
-> (NtpOffset -> Integer)
-> Integral NtpOffset
NtpOffset -> Integer
NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset)
NtpOffset -> NtpOffset -> NtpOffset
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: NtpOffset -> NtpOffset -> NtpOffset
quot :: NtpOffset -> NtpOffset -> NtpOffset
$crem :: NtpOffset -> NtpOffset -> NtpOffset
rem :: NtpOffset -> NtpOffset -> NtpOffset
$cdiv :: NtpOffset -> NtpOffset -> NtpOffset
div :: NtpOffset -> NtpOffset -> NtpOffset
$cmod :: NtpOffset -> NtpOffset -> NtpOffset
mod :: NtpOffset -> NtpOffset -> NtpOffset
$cquotRem :: NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset)
quotRem :: NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset)
$cdivMod :: NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset)
divMod :: NtpOffset -> NtpOffset -> (NtpOffset, NtpOffset)
$ctoInteger :: NtpOffset -> Integer
toInteger :: NtpOffset -> Integer
Integral, Integer -> NtpOffset
NtpOffset -> NtpOffset
NtpOffset -> NtpOffset -> NtpOffset
(NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset)
-> (Integer -> NtpOffset)
-> Num NtpOffset
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: NtpOffset -> NtpOffset -> NtpOffset
+ :: NtpOffset -> NtpOffset -> NtpOffset
$c- :: NtpOffset -> NtpOffset -> NtpOffset
- :: NtpOffset -> NtpOffset -> NtpOffset
$c* :: NtpOffset -> NtpOffset -> NtpOffset
* :: NtpOffset -> NtpOffset -> NtpOffset
$cnegate :: NtpOffset -> NtpOffset
negate :: NtpOffset -> NtpOffset
$cabs :: NtpOffset -> NtpOffset
abs :: NtpOffset -> NtpOffset
$csignum :: NtpOffset -> NtpOffset
signum :: NtpOffset -> NtpOffset
$cfromInteger :: Integer -> NtpOffset
fromInteger :: Integer -> NtpOffset
Num, Eq NtpOffset
Eq NtpOffset =>
(NtpOffset -> NtpOffset -> Ordering)
-> (NtpOffset -> NtpOffset -> Bool)
-> (NtpOffset -> NtpOffset -> Bool)
-> (NtpOffset -> NtpOffset -> Bool)
-> (NtpOffset -> NtpOffset -> Bool)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> (NtpOffset -> NtpOffset -> NtpOffset)
-> Ord NtpOffset
NtpOffset -> NtpOffset -> Bool
NtpOffset -> NtpOffset -> Ordering
NtpOffset -> NtpOffset -> NtpOffset
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: NtpOffset -> NtpOffset -> Ordering
compare :: NtpOffset -> NtpOffset -> Ordering
$c< :: NtpOffset -> NtpOffset -> Bool
< :: NtpOffset -> NtpOffset -> Bool
$c<= :: NtpOffset -> NtpOffset -> Bool
<= :: NtpOffset -> NtpOffset -> Bool
$c> :: NtpOffset -> NtpOffset -> Bool
> :: NtpOffset -> NtpOffset -> Bool
$c>= :: NtpOffset -> NtpOffset -> Bool
>= :: NtpOffset -> NtpOffset -> Bool
$cmax :: NtpOffset -> NtpOffset -> NtpOffset
max :: NtpOffset -> NtpOffset -> NtpOffset
$cmin :: NtpOffset -> NtpOffset -> NtpOffset
min :: NtpOffset -> NtpOffset -> NtpOffset
Ord, Num NtpOffset
Ord NtpOffset
(Num NtpOffset, Ord NtpOffset) =>
(NtpOffset -> Rational) -> Real NtpOffset
NtpOffset -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: NtpOffset -> Rational
toRational :: NtpOffset -> Rational
Real, Int -> NtpOffset -> ShowS
[NtpOffset] -> ShowS
NtpOffset -> String
(Int -> NtpOffset -> ShowS)
-> (NtpOffset -> String)
-> ([NtpOffset] -> ShowS)
-> Show NtpOffset
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NtpOffset -> ShowS
showsPrec :: Int -> NtpOffset -> ShowS
$cshow :: NtpOffset -> String
show :: NtpOffset -> String
$cshowList :: [NtpOffset] -> ShowS
showList :: [NtpOffset] -> ShowS
Show)
clockOffsetPure :: NtpPacket -> Microsecond -> NtpOffset
clockOffsetPure :: NtpPacket -> Microsecond -> NtpOffset
clockOffsetPure NtpPacket{Int8
Word8
Microsecond
ntpParams :: NtpPacket -> Word8
ntpPoll :: NtpPacket -> Int8
ntpOriginTime :: NtpPacket -> Microsecond
ntpReceivedTime :: NtpPacket -> Microsecond
ntpTransmitTime :: NtpPacket -> Microsecond
ntpParams :: Word8
ntpPoll :: Int8
ntpOriginTime :: Microsecond
ntpReceivedTime :: Microsecond
ntpTransmitTime :: Microsecond
..} Microsecond
localTime = Microsecond -> NtpOffset
NtpOffset
(Microsecond -> NtpOffset) -> Microsecond -> NtpOffset
forall a b. (a -> b) -> a -> b
$ (Microsecond
ntpReceivedTime Microsecond -> Microsecond -> Microsecond
forall a. Num a => a -> a -> a
- Microsecond
ntpOriginTime Microsecond -> Microsecond -> Microsecond
forall a. Num a => a -> a -> a
+ Microsecond
ntpTransmitTime Microsecond -> Microsecond -> Microsecond
forall a. Num a => a -> a -> a
- Microsecond
localTime)
Microsecond -> Microsecond -> Microsecond
forall a. Integral a => a -> a -> a
`div` Microsecond
2
clockOffset
:: Microsecond
-> NtpPacket
-> IO (Maybe NtpOffset)
clockOffset :: Microsecond -> NtpPacket -> IO (Maybe NtpOffset)
clockOffset Microsecond
respTimeout NtpPacket
packet = do
time <- IO Microsecond
getCurrentTime
let isLate = Microsecond
time Microsecond -> Microsecond -> Microsecond
forall a. Num a => a -> a -> a
- NtpPacket -> Microsecond
ntpOriginTime NtpPacket
packet Microsecond -> Microsecond -> Bool
forall a. Ord a => a -> a -> Bool
>= Microsecond
respTimeout
if isLate
then return Nothing
else return $ Just $ clockOffsetPure packet time
getCurrentTime :: IO Microsecond
getCurrentTime :: IO Microsecond
getCurrentTime = Integer -> Microsecond
Microsecond (Integer -> Microsecond)
-> (POSIXTime -> Integer) -> POSIXTime -> Microsecond
forall b c a. (b -> c) -> (a -> b) -> a -> c
. POSIXTime -> Integer
forall b. Integral b => POSIXTime -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (POSIXTime -> Integer)
-> (POSIXTime -> POSIXTime) -> POSIXTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( POSIXTime -> POSIXTime -> POSIXTime
forall a. Num a => a -> a -> a
* POSIXTime
1000000) (POSIXTime -> Microsecond) -> IO POSIXTime -> IO Microsecond
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO POSIXTime
getPOSIXTime