{-# LANGUAGE DeriveDataTypeable #-} module Data.Tox.Relay where import Data.ByteString import Data.Data import Data.Serialize import Data.Word import Crypto.Tox import Network.Tox.Onion.Transport import Network.Tox.NodeId (key2id,id2key) data RelayPacket = RoutingRequest PublicKey | RoutingResponse Word8 PublicKey | ConnectNotification Word8 | DisconnectNotification Word8 | RelayPing Word64 | RelayPong Word64 | OOBSend PublicKey ByteString | OOBRecv PublicKey ByteString | OnionPacket (OnionRequest N0) | OnionPacketResponse (OnionResponse N1) -- 0x0A through 0x0F reserved for future use. | RelayData Word8 ByteString -- Word8 is a connection id. Encoded as number 16 to 255. deriving (Eq,Ord,Show,Data) packetNumber :: RelayPacket -> Word8 packetNumber (RelayData conid _) = conid -- 0 to 15 not allowed. packetNumber rp = fromIntegral $ pred $ constrIndex $ toConstr rp instance Serialize RelayPacket where get = do pktid <- getWord8 case pktid of 0 -> RoutingRequest <$> (id2key <$> get) 1 -> RoutingResponse <$> getWord8 <*> (id2key <$> get) 2 -> ConnectNotification <$> getWord8 3 -> DisconnectNotification <$> getWord8 4 -> RelayPing <$> getWord64be 5 -> RelayPong <$> getWord64be 6 -> OOBSend <$> (id2key <$> get) <*> (remaining >>= getBytes) 7 -> OOBRecv <$> (id2key <$> get) <*> (remaining >>= getBytes) 8 -> OnionPacket <$> get 9 -> OnionPacketResponse <$> get conid -> RelayData conid <$> (remaining >>= getBytes) put rp = do putWord8 $ packetNumber rp case rp of RoutingRequest k -> put (key2id k) RoutingResponse rpid k -> putWord8 rpid >> put (key2id k) ConnectNotification conid -> putWord8 conid DisconnectNotification conid -> putWord8 conid RelayPing pingid -> putWord64be pingid RelayPong pingid -> putWord64be pingid OOBSend k bs -> put (key2id k) >> putByteString bs OOBRecv k bs -> put (key2id k) >> putByteString bs OnionPacket query -> put query OnionPacketResponse answer -> put answer RelayData _ bs -> putByteString bs