ntrip-client (empty) → 0.1.0
raw patch · 3 files changed
+85/−0 lines, 3 filesdep +asyncdep +attoparsecdep +basesetup-changed
Dependencies added: async, attoparsec, base, base64-bytestring, basic-prelude, case-insensitive, conduit, conduit-extra, http-types
Files
- Setup.hs +2/−0
- ntrip-client.cabal +27/−0
- src/Network/Ntrip/Client.hs +56/−0
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ntrip-client.cabal view
@@ -0,0 +1,27 @@+name: ntrip-client+version: 0.1.0+synopsis: NTRIP client.+description: Networked Transport of RTCM via Internet Protocol client.+license: BSD3+author: Swift Navigation Inc.+maintainer: Mark Fine <dev@swiftnav.com>+copyright: Copyright (C) 2016 Swift Navigation, Inc.+category: Network+build-type: Simple+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Network.Ntrip.Client+ ghc-options: -Wall+ default-language: Haskell2010+ build-depends: async,+ async,+ attoparsec,+ base >= 4.7 && < 5,+ base64-bytestring,+ basic-prelude,+ case-insensitive,+ conduit,+ conduit-extra,+ http-types
+ src/Network/Ntrip/Client.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Network.Ntrip.Client where++import BasicPrelude+import Control.Concurrent.Async+import Data.Attoparsec.ByteString+import Data.Attoparsec.ByteString.Char8 (decimal, endOfLine, isEndOfLine)+import Data.ByteString.Base64+import Data.CaseInsensitive+import Data.Conduit+import Data.Conduit.Attoparsec+import Data.Conduit.Network+import Network.HTTP.Types++tcpClient :: ByteString -> Int -> Source IO ByteString -> Sink ByteString IO () -> IO ()+tcpClient host port source sink =+ runTCPClient (clientSettings port host) $ \ad ->+ void $ concurrently (source $$ appSink ad) (appSource ad $$ sink)++sourceNtrip :: ByteString -> ByteString -> ByteString -> Source IO ByteString -> Source IO ByteString+sourceNtrip path user password source = do+ yield $ intercalate "\r\n" $+ [ methodGet <> " " <> path <> " HTTP/1.0"+ , original hUserAgent <> ": NTRIP ntrip-client/0.0"+ , original hAuthorization <> ": " <> encode (user <> ":" <> password)+ , ""+ , ""+ ]+ source++parseNtrip :: Parser (ByteString, Status)+parseNtrip = do+ format <- parseFormat+ code <- parseCode+ message <- parseMessage+ return (format, Status code message)+ where+ takeSpace = takeWhile1 (== 32)+ takeInClass = takeWhile1 . inClass+ takeEndOfLine1 = takeWhile1 (not . isEndOfLine)+ parseFormat = takeInClass "a-zA-Z0-9/." <* takeSpace+ parseCode = decimal <* takeSpace+ parseMessage = takeEndOfLine1 <* endOfLine++sinkNtrip :: Sink ByteString IO () -> Sink ByteString IO ()+sinkNtrip sink = do+ (format, status) <- sinkParser parseNtrip+ unless (format == "ICY") $ throwIO $ userError "Unsupported format"+ unless (status == status200) $ throwIO $ userError "Bad status"+ sink++runNtrip :: ByteString -> Int -> ByteString -> ByteString -> ByteString -> Source IO ByteString -> Sink ByteString IO () -> IO ()+runNtrip host port path user password source sink =+ tcpClient host port (sourceNtrip path user password source) (sinkNtrip sink)