module Network.DNSSD (dnsBrowse, dnsResolve, SRecord(..), SResolved(..)) where
import Foreign.C
import Foreign
import Data.IORef
import Data.List
data SRecord = SRecord { deviceName :: String
, serviceName :: String
, deviceDomain :: String
} deriving (Show, Eq)
data SResolved = SResolved { fullname :: String
, hosttarget :: String
, port :: Int
, txt :: String
} deriving (Show)
foreign import ccall "resolve.h dns_sd_browse" c_browse :: CString -> Ptr () -> IO CInt
foreign import ccall "resolve.h dns_sd_resolve" c_resolve :: CString -> CString -> Ptr () -> IO CInt
foreign import ccall "ntohs" ntohs :: CUShort -> IO CUShort
dnsBrowse :: String -> IO [SRecord]
dnsBrowse s = do
ref <- newIORef []
ptr <- newStablePtr ref
cstr <- newCString s
_ <- c_browse cstr (castStablePtrToPtr ptr)
fmap nub $ readIORef ref
foreign export ccall dns_sd_browse_callback :: Ptr () -> CUInt -> CUInt -> CUInt -> CString -> CString -> CString -> Ptr () -> IO ()
dns_sd_browse_callback :: Ptr () -> CUInt -> CUInt -> CUInt -> CString -> CString -> CString -> Ptr () -> IO ()
dns_sd_browse_callback _ref _fla _int _err name typ domain cont = do
ref <- deRefStablePtr $ castPtrToStablePtr cont
f <- peekCString name
g <- peekCString typ
h <- peekCString domain
modifyIORef ref (++ [SRecord f g h])
dnsResolve :: SRecord -> IO (Maybe SResolved)
dnsResolve (SRecord d s _dom) = do
ref <- newIORef Nothing
ptr <- newStablePtr ref
dstr <- newCString d
sstr <- newCString s
_ <- c_resolve dstr sstr (castStablePtrToPtr ptr)
readIORef ref
foreign export ccall dns_sd_resolve_callback :: Ptr () -> CUInt -> CUInt -> CUInt -> CString -> CString -> CUShort -> CUShort -> CString -> Ptr () -> IO ()
dns_sd_resolve_callback :: Ptr () -> CUInt -> CUInt -> CUInt -> CString -> CString -> CUShort -> CUShort -> CString -> Ptr () -> IO ()
dns_sd_resolve_callback _ref _fla _int _err name host po txtLen txtrec cont = do
ref <- deRefStablePtr $ castPtrToStablePtr cont
f <- peekCString name
g <- peekCString host
p <- ntohs po
t <- peekCStringLen (txtrec, fromIntegral txtLen)
writeIORef ref (Just $ SResolved f g (fromIntegral p) t)