{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ViewPatterns #-} module Network.Tox.Avahi ( module Network.Tox.Avahi , NodeInfo(..) , NodeId(..) ) where import Data.Foldable import Network.Address import Network.Avahi import Network.Tox.NodeId import Text.Read toxServiceName :: String toxServiceName = "_tox_dht._udp" toxServiceDomain :: String toxServiceDomain = "local" (<.>) :: String -> String -> String a <.> b = a ++ "." ++ b toxService :: String -> PortNumber -> NodeId -> Service toxService hostname (fromIntegral -> port) (show -> extra) = Service { serviceProtocol = PROTO_UNSPEC, serviceName = "Tox DHT @ " ++ hostname, serviceType = toxServiceName, serviceDomain = toxServiceDomain, serviceHost = if null hostname then "" else hostname <.> toxServiceDomain, serviceAddress = Nothing, servicePort = port, serviceText = extra } announceToxServiceWithHostname :: String -> PortNumber -> NodeId -> IO () announceToxServiceWithHostname = ((.).(.).(.)) announce toxService announceToxService :: PortNumber -> NodeId -> IO () announceToxService = announceToxServiceWithHostname "" queryToxService :: (NodeInfo -> IO ()) -> IO () queryToxService cb = browse $ BrowseQuery { lookupProtocol = PROTO_UNSPEC , lookupServiceName = toxServiceName , lookupDomain = toxServiceDomain , lookupCallback = runCallback } where runCallback x@Service {..} = do let nid = readMaybe serviceText addr = readMaybe =<< serviceAddress p = fromIntegral servicePort forM_ nid $ \n -> forM_ addr $ \a -> cb (NodeInfo n a p)