summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Presence/XMPP.hs101
-rw-r--r--Presence/XMPPServer.hs4
-rw-r--r--Presence/XMPPTypes.hs3
-rw-r--r--Presence/main.hs2
4 files changed, 99 insertions, 11 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index e158eea2..248d1ffb 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -1,4 +1,5 @@
1{-# LANGUAGE FlexibleContexts #-} 1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE FlexibleContexts #-}
2module XMPP 3module XMPP
3 ( module XMPPTypes 4 ( module XMPPTypes
4 , listenForXmppClients 5 , listenForXmppClients
@@ -9,19 +10,105 @@ module XMPP
9 10
10import ServerC 11import ServerC
11import XMPPTypes 12import XMPPTypes
13import SocketLike
14import ByteStringOperators
12 15
13import Data.HList 16import Data.HList
14import Network.Socket (Family) 17import Network.Socket (Family)
15import Network.BSD (PortNumber) 18import Network.BSD (PortNumber)
16import Control.Concurrent.STM 19import Control.Concurrent.STM
20import Data.Conduit
21import qualified Data.Conduit.List as CL
22import Data.ByteString (ByteString)
23import qualified Data.ByteString.Lazy.Char8 as L
24 ( putStrLn
25 )
26import Control.Concurrent (forkIO,killThread)
27import Control.Exception (handle,SomeException(..),finally)
28import Control.Monad.IO.Class
29import Control.Monad.Trans.Maybe
30import Todo
31import Control.Monad as Monad
32import Text.XML.Stream.Parse
17 33
18listenForXmppClients 34data Commands x = Send [x] | QuitThread
19 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) => 35 deriving Prelude.Show
20 Family -> XMPPClass t -> e -> l -> IO ServerHandle 36
37xmlifyPresenceForClient :: Presence -> IO [x]
38xmlifyPresenceForClient presence = todo
39
40handleClient
41 :: (SocketLike sock, HHead l (XMPPClass session),
42 XMPPSession session) =>
43 HCons sock (HCons t l) -> Source IO ByteString -> Sink ByteString IO () -> IO ()
44handleClient st src snk = do
45 let HCons sock (HCons _ st') = st
46 session_factory = hHead st'
47 pname <- getPeerName sock
48 session <- newSession session_factory sock
49 Prelude.putStrLn $ "PEER NAME: "++Prelude.show pname
50 pchan <- subscribe session Nothing
51 cmdChan <- atomically newTChan
52
53
54 {-
55 reader <- forkIO $ do
56 flip ($$) snk $
57 handle (\(SomeException e) -> liftIO (L.putStrLn $ "quit reader via exception: "<++>bshow e) >> return ()) $
58 fix $ \loop -> do
59 event <- liftIO . atomically $
60 (fmap Left $ readTChan pchan)
61 `orElse`
62 (fmap Right $ readTChan cmdChan)
63 case event of
64 Left presence -> do
65 liftIO (L.putStrLn $ "PRESENCE: " <++> bshow presence)
66 -- TODO: it violates spec to send presence information before
67 -- a resource is bound.
68 -- r <- xmlifyPresenceForClient presence
69 -- yield r
70 -- -- hPutStrLn h r
71 -- liftIO (L.putStrLn $ "\nOUT client:\n" <++> r)
72 Right (Send r) ->
73 mapM_ yield r
74 -- yield r
75 -- -- hPutStrLn h r
76 loop
77 -}
78 let outgoing = do
79 event <- liftIO . atomically $
80 (fmap Left $ readTChan pchan)
81 `orElse`
82 (fmap Right $ readTChan cmdChan)
83 case event of
84 Right QuitThread -> return ()
85 Left presence -> do
86 xs <- liftIO $ xmlifyPresenceForClient presence
87 Monad.mapM_ yield xs
88 outgoing
89
90 incomming = do
91 mb <- await
92 maybe (return ())
93 (\packet -> do
94 liftIO (L.putStrLn $ "client-in: " <++> bshow packet)
95 incomming)
96 mb
97
98 sendingThread <- forkIO (outgoing $$ snk)
99 let quit = do
100 atomically $ writeTChan cmdChan QuitThread
101 closeSession session
102 -- killThread sendingThread
103 finally ( src $= parseBytes def $$ incomming )
104 quit
105
106listenForXmppClients ::
107 (HList l, HHead l (XMPPClass session), HExtend e1 l2 l1,
108 HExtend e l1 (HCons PortNumber l), XMPPSession session) =>
109 Family -> e1 -> e -> l2 -> IO ServerHandle
21listenForXmppClients addr_family session_factory port st = do 110listenForXmppClients addr_family session_factory port st = do
22 putStrLn "unimplemented: listenForXmppClients" 111 doServer (addr_family .*. port .*. session_factory .*. st) handleClient
23 dummyServerHandle
24 -- TODO
25 112
26listenForRemotePeers 113listenForRemotePeers
27 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) => 114 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) =>
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index 813c7c7b..f607989d 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -160,7 +160,7 @@ startCon session_factory sock st = do
160 -- cred <- getLocalPeerCred sock 160 -- cred <- getLocalPeerCred sock
161 -- Prelude.putStrLn $ "PEER CRED: "++Prelude.show cred 161 -- Prelude.putStrLn $ "PEER CRED: "++Prelude.show cred
162 pname <- getPeerName sock 162 pname <- getPeerName sock
163 session <- newSession session_factory sock h 163 session <- newSession session_factory sock
164 Prelude.putStrLn $ "PEER NAME: "++Prelude.show pname 164 Prelude.putStrLn $ "PEER NAME: "++Prelude.show pname
165 pchan <- subscribe session Nothing 165 pchan <- subscribe session Nothing
166 cmdChan <- atomically newTChan 166 cmdChan <- atomically newTChan
@@ -418,7 +418,7 @@ startPeer session_factory sock st = do
418 name <- fmap bshow $ getPeerName sock 418 name <- fmap bshow $ getPeerName sock
419 L.putStrLn $ "IN peer: connected " <++> name 419 L.putStrLn $ "IN peer: connected " <++> name
420 jids <- newTVarIO Set.empty 420 jids <- newTVarIO Set.empty
421 session <- newSession session_factory sock h 421 session <- newSession session_factory sock
422 let quit = do 422 let quit = do
423 L.putStrLn $ "IN peer: disconnected " <++> name 423 L.putStrLn $ "IN peer: disconnected " <++> name
424 js <- fmap Set.toList (readTVarIO jids) 424 js <- fmap Set.toList (readTVarIO jids)
diff --git a/Presence/XMPPTypes.hs b/Presence/XMPPTypes.hs
index eb5d349e..e3bbfd16 100644
--- a/Presence/XMPPTypes.hs
+++ b/Presence/XMPPTypes.hs
@@ -11,10 +11,11 @@ import Data.Binary.Builder as B
11import Data.Binary.Put 11import Data.Binary.Put
12import Control.DeepSeq 12import Control.DeepSeq
13import ByteStringOperators 13import ByteStringOperators
14import SocketLike
14 15
15class XMPPSession session where 16class XMPPSession session where
16 data XMPPClass session 17 data XMPPClass session
17 newSession :: XMPPClass session -> Socket -> Handle -> IO session 18 newSession :: SocketLike sock => XMPPClass session -> sock -> IO session
18 setResource :: session -> ByteString -> IO () 19 setResource :: session -> ByteString -> IO ()
19 getJID :: session -> IO JID 20 getJID :: session -> IO JID
20 closeSession :: session -> IO () 21 closeSession :: session -> IO ()
diff --git a/Presence/main.hs b/Presence/main.hs
index 403a6ac7..9a09b855 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -63,7 +63,7 @@ data UnixSession = UnixSession {
63 63
64instance XMPPSession UnixSession where 64instance XMPPSession UnixSession where
65 data XMPPClass UnixSession = UnixSessions PresenceState 65 data XMPPClass UnixSession = UnixSessions PresenceState
66 newSession (UnixSessions state) sock handle = do 66 newSession (UnixSessions state) sock = do
67 muid <- getLocalPeerCred sock 67 muid <- getLocalPeerCred sock
68 L.putStrLn $ "SESSION: open " <++> bshow muid 68 L.putStrLn $ "SESSION: open " <++> bshow muid
69 uid_ref <- newIORef muid 69 uid_ref <- newIORef muid