diff options
Diffstat (limited to 'src/Data/Tox/Relay.hs')
-rw-r--r-- | src/Data/Tox/Relay.hs | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/Data/Tox/Relay.hs b/src/Data/Tox/Relay.hs index 02300866..d1e9fb99 100644 --- a/src/Data/Tox/Relay.hs +++ b/src/Data/Tox/Relay.hs | |||
@@ -8,16 +8,24 @@ | |||
8 | {-# LANGUAGE UndecidableInstances #-} | 8 | {-# LANGUAGE UndecidableInstances #-} |
9 | module Data.Tox.Relay where | 9 | module Data.Tox.Relay where |
10 | 10 | ||
11 | import Data.Aeson (ToJSON(..),FromJSON(..)) | ||
12 | import qualified Data.Aeson as JSON | ||
11 | import Data.ByteString as B | 13 | import Data.ByteString as B |
12 | import Data.Data | 14 | import Data.Data |
13 | import Data.Functor.Contravariant | 15 | import Data.Functor.Contravariant |
16 | import Data.Hashable | ||
17 | import qualified Data.HashMap.Strict as HashMap | ||
14 | import Data.Monoid | 18 | import Data.Monoid |
15 | import Data.Serialize | 19 | import Data.Serialize |
20 | import qualified Data.Vector as Vector | ||
16 | import Data.Word | 21 | import Data.Word |
22 | import Network.Socket | ||
17 | import qualified Rank2 | 23 | import qualified Rank2 |
24 | import qualified Text.ParserCombinators.ReadP as RP | ||
18 | 25 | ||
19 | import Crypto.Tox | 26 | import Crypto.Tox |
20 | import Network.Tox.Onion.Transport | 27 | import Data.Tox.Onion |
28 | import qualified Network.Tox.NodeId as UDP | ||
21 | 29 | ||
22 | newtype ConId = ConId Word8 | 30 | newtype ConId = ConId Word8 |
23 | deriving (Eq,Show,Ord,Data,Serialize) | 31 | deriving (Eq,Show,Ord,Data,Serialize) |
@@ -178,3 +186,40 @@ instance Sized (Welcome Encrypted) where | |||
178 | instance Serialize (Welcome Encrypted) where | 186 | instance Serialize (Welcome Encrypted) where |
179 | get = Welcome <$> get <*> get | 187 | get = Welcome <$> get <*> get |
180 | put (Welcome n dta) = put n >> put dta | 188 | put (Welcome n dta) = put n >> put dta |
189 | |||
190 | data NodeInfo = NodeInfo | ||
191 | { udpNodeInfo :: UDP.NodeInfo | ||
192 | , tcpPort :: PortNumber | ||
193 | } | ||
194 | deriving (Eq,Ord) | ||
195 | |||
196 | instance Read NodeInfo where | ||
197 | readsPrec _ = RP.readP_to_S $ do | ||
198 | udp <- RP.readS_to_P reads | ||
199 | port <- RP.between (RP.char '{') (RP.char '}') $ do | ||
200 | mapM_ RP.char ("tcp:" :: String) | ||
201 | w16 <- RP.readS_to_P reads | ||
202 | return $ fromIntegral (w16 :: Word16) | ||
203 | return $ NodeInfo udp port | ||
204 | |||
205 | instance ToJSON NodeInfo where | ||
206 | toJSON (NodeInfo udp port) = case (toJSON udp) of | ||
207 | JSON.Object tbl -> JSON.Object $ HashMap.insert "tcp_ports" | ||
208 | (JSON.Array $ Vector.fromList | ||
209 | [JSON.Number (fromIntegral port)]) | ||
210 | tbl | ||
211 | x -> x -- Shouldn't happen. | ||
212 | |||
213 | instance FromJSON NodeInfo where | ||
214 | parseJSON json = do | ||
215 | udp <- parseJSON json | ||
216 | port <- case json of | ||
217 | JSON.Object v -> do | ||
218 | portnum:_ <- v JSON..: "tcp_ports" | ||
219 | return (fromIntegral (portnum :: Word16)) | ||
220 | _ -> fail "TCP.NodeInfo: Expected JSON object." | ||
221 | return $ NodeInfo udp port | ||
222 | |||
223 | instance Hashable NodeInfo where | ||
224 | hashWithSalt s n = hashWithSalt s (udpNodeInfo n) | ||
225 | |||