diff options
-rw-r--r-- | Presence/XMPPServer.hs | 4 | ||||
-rw-r--r-- | TraversableT.hs | 6 | ||||
-rw-r--r-- | xmppServer.hs | 36 |
3 files changed, 41 insertions, 5 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs index 7fc11124..b9719fa4 100644 --- a/Presence/XMPPServer.hs +++ b/Presence/XMPPServer.hs | |||
@@ -183,6 +183,7 @@ data XMPPServerParameters = | |||
183 | , xmppTellClientNameOfPeer :: ConnectionKey -> IO Text | 183 | , xmppTellClientNameOfPeer :: ConnectionKey -> IO Text |
184 | , xmppDeliverMessage :: (IO ()) -> Stanza -> IO () | 184 | , xmppDeliverMessage :: (IO ()) -> Stanza -> IO () |
185 | , xmppInformClientPresence :: ConnectionKey -> Stanza -> IO () | 185 | , xmppInformClientPresence :: ConnectionKey -> Stanza -> IO () |
186 | , xmppInformPeerPresence :: ConnectionKey -> Stanza -> IO () | ||
186 | , xmppAnswerProbe :: ConnectionKey -> Stanza -> TChan Stanza -> IO () | 187 | , xmppAnswerProbe :: ConnectionKey -> Stanza -> TChan Stanza -> IO () |
187 | } | 188 | } |
188 | 189 | ||
@@ -1168,6 +1169,7 @@ forkConnection sv xmpp k laddr pingflag src snk stanzas = do | |||
1168 | _ -> return () | 1169 | _ -> return () |
1169 | stanzaToConduit stanza =$= wrapStanzaConduit stanza | 1170 | stanzaToConduit stanza =$= wrapStanzaConduit stanza |
1170 | $$ awaitForever | 1171 | $$ awaitForever |
1172 | -- TODO: PresenceStatus stanzas should be pushed to appropriate slots | ||
1171 | $ liftIO . atomically . Slotted.push slots Nothing | 1173 | $ liftIO . atomically . Slotted.push slots Nothing |
1172 | case stanzaType stanza of | 1174 | case stanzaType stanza of |
1173 | Error err tag | tagName tag=="{jabber:client}message" -> do | 1175 | Error err tag | tagName tag=="{jabber:client}message" -> do |
@@ -1578,6 +1580,8 @@ monitor sv params xmpp = do | |||
1578 | case stanzaType stanza of | 1580 | case stanzaType stanza of |
1579 | PresenceRequestStatus {} -> do | 1581 | PresenceRequestStatus {} -> do |
1580 | xmppAnswerProbe xmpp k stanza replyto | 1582 | xmppAnswerProbe xmpp k stanza replyto |
1583 | PresenceStatus {} -> do | ||
1584 | xmppInformPeerPresence xmpp k stanza | ||
1581 | _ -> return () | 1585 | _ -> return () |
1582 | _ -> return () | 1586 | _ -> return () |
1583 | let deliver replyto = do | 1587 | let deliver replyto = do |
diff --git a/TraversableT.hs b/TraversableT.hs index cd04731c..98a97bf6 100644 --- a/TraversableT.hs +++ b/TraversableT.hs | |||
@@ -5,6 +5,7 @@ import Control.Monad (join,MonadPlus(..)) | |||
5 | import Control.Monad.Trans.Class | 5 | import Control.Monad.Trans.Class |
6 | import Control.Applicative | 6 | import Control.Applicative |
7 | import Data.Foldable (Foldable(foldMap)) | 7 | import Data.Foldable (Foldable(foldMap)) |
8 | import Data.Maybe (maybeToList) | ||
8 | 9 | ||
9 | -- | | 10 | -- | |
10 | -- | 11 | -- |
@@ -75,4 +76,9 @@ liftCatch :: (m (t a) -> (e -> m (t a)) -> m (t a)) -> | |||
75 | liftCatch catchError m h = TraversableT $ runTraversableT m | 76 | liftCatch catchError m h = TraversableT $ runTraversableT m |
76 | `catchError` \e -> runTraversableT (h e) | 77 | `catchError` \e -> runTraversableT (h e) |
77 | 78 | ||
79 | liftMaybe :: Monad m => Maybe a -> TraversableT [] m a | ||
80 | liftMaybe = liftT . maybeToList | ||
81 | |||
82 | liftIOMaybe :: IO (Maybe a) -> TraversableT [] IO a | ||
83 | liftIOMaybe = liftMT . fmap maybeToList | ||
78 | 84 | ||
diff --git a/xmppServer.hs b/xmppServer.hs index 3899a258..8656c91f 100644 --- a/xmppServer.hs +++ b/xmppServer.hs | |||
@@ -221,16 +221,21 @@ rosterGetStuff what state k = forClient state k (return []) | |||
221 | peers <- atomically $ readTVar (associatedPeers state) | 221 | peers <- atomically $ readTVar (associatedPeers state) |
222 | addrs <- return $ addrs `Map.difference` peers | 222 | addrs <- return $ addrs `Map.difference` peers |
223 | sv <- atomically $ takeTMVar $ server state | 223 | sv <- atomically $ takeTMVar $ server state |
224 | -- Grok peers to associate with from the roster: | ||
224 | forM_ (Map.keys addrs) $ \addr -> do | 225 | forM_ (Map.keys addrs) $ \addr -> do |
225 | putStrLn $ "new addr: "++show addr | 226 | putStrLn $ "new addr: "++show addr |
226 | addPeer sv addr | 227 | addPeer sv addr |
228 | -- Update local set of associated peers | ||
227 | atomically $ do | 229 | atomically $ do |
228 | writeTVar (associatedPeers state) (addrs `Map.union` peers) | 230 | writeTVar (associatedPeers state) (addrs `Map.union` peers) |
229 | putTMVar (server state) sv | 231 | putTMVar (server state) sv |
230 | return jids | 232 | return jids |
231 | 233 | ||
232 | rosterGetBuddies :: PresenceState -> ConnectionKey -> IO [Text] | 234 | rosterGetBuddies :: PresenceState -> ConnectionKey -> IO [Text] |
233 | rosterGetBuddies = rosterGetStuff ConfigFiles.getBuddies | 235 | rosterGetBuddies state k = do |
236 | buds <- rosterGetStuff ConfigFiles.getBuddies state k | ||
237 | return buds | ||
238 | |||
234 | rosterGetSolicited = rosterGetStuff ConfigFiles.getSolicited | 239 | rosterGetSolicited = rosterGetStuff ConfigFiles.getSolicited |
235 | rosterGetOthers = rosterGetStuff ConfigFiles.getOthers | 240 | rosterGetOthers = rosterGetStuff ConfigFiles.getOthers |
236 | rosterGetSubscribers = rosterGetStuff ConfigFiles.getSubscribers | 241 | rosterGetSubscribers = rosterGetStuff ConfigFiles.getSubscribers |
@@ -413,23 +418,43 @@ informClientPresence state k stanza = do | |||
413 | flip (maybe $ return ()) mb $ \cstate -> do | 418 | flip (maybe $ return ()) mb $ \cstate -> do |
414 | writeTVar (clientStatus cstate) $ Just dup | 419 | writeTVar (clientStatus cstate) $ Just dup |
415 | 420 | ||
421 | informPeerPresence state k stanza = do | ||
422 | -- Presence must indicate full JID with resource... | ||
423 | flip (maybe $ return ()) (stanzaFrom stanza) $ \from -> do | ||
424 | let (muser,h,mresource) = splitJID from | ||
425 | flip (maybe $ return ()) mresource $ \resource -> do | ||
426 | flip (maybe $ return ()) muser $ \user -> do | ||
427 | |||
428 | clients <- atomically $ do | ||
429 | -- TODO: Store the stanza | ||
430 | -- For now, all clients: | ||
431 | -- (TODO: interested/authorized clients only.) | ||
432 | ktc <- readTVar (keyToChan state) | ||
433 | runTraversableT $ do | ||
434 | (k,client) <- liftMT $ fmap Map.toList $ readTVar (clients state) | ||
435 | con <- liftMaybe $ Map.lookup k ktc | ||
436 | return (k,con,client) | ||
437 | forM_ clients $ \(k,con,client) -> do | ||
438 | from' <- do | ||
439 | let ClientKey laddr = k | ||
440 | (_,trip) <- rewriteJIDForClient laddr from | ||
441 | return trip | ||
442 | sendModifiedStanzaToClient stanza (connChan con) | ||
443 | |||
416 | answerProbe state k stanza chan = do | 444 | answerProbe state k stanza chan = do |
417 | putStrLn $ "answerProbe! " ++ show (stanzaType stanza) | 445 | putStrLn $ "answerProbe! " ++ show (stanzaType stanza) |
418 | ktc <- atomically $ readTVar (keyToChan state) | 446 | ktc <- atomically $ readTVar (keyToChan state) |
419 | replies <- runTraversableT $ do | 447 | replies <- runTraversableT $ do |
420 | let liftMaybe = liftT . maybeToList | ||
421 | liftIOMaybe :: IO (Maybe a) -> TraversableT [] IO a | ||
422 | liftIOMaybe = liftMT . fmap maybeToList | ||
423 | to <- liftMaybe $ stanzaTo stanza | 448 | to <- liftMaybe $ stanzaTo stanza |
424 | conn <- liftMaybe $ Map.lookup k ktc | 449 | conn <- liftMaybe $ Map.lookup k ktc |
425 | let (mu,h,_) = splitJID to -- TODO: currently resource-id is ignored on presence | 450 | let (mu,h,_) = splitJID to -- TODO: currently resource-id is ignored on presence |
426 | -- probes. Is this correct? Check the spec. | 451 | -- probes. Is this correct? Check the spec. |
452 | liftIOMaybe $ guardPortStrippedAddress h (auxAddr conn) | ||
427 | u <- liftMaybe mu | 453 | u <- liftMaybe mu |
428 | cbu <- lift . atomically $ readTVar (clientsByUser state) | 454 | cbu <- lift . atomically $ readTVar (clientsByUser state) |
429 | lpres <- liftMaybe $ Map.lookup u cbu | 455 | lpres <- liftMaybe $ Map.lookup u cbu |
430 | clientState <- liftT $ Map.elems (networkClients lpres) | 456 | clientState <- liftT $ Map.elems (networkClients lpres) |
431 | stanza <- liftIOMaybe $ atomically (readTVar (clientStatus clientState)) | 457 | stanza <- liftIOMaybe $ atomically (readTVar (clientStatus clientState)) |
432 | -- TODO: from address!! | ||
433 | let jid = unsplitJID (Just $ clientUser clientState | 458 | let jid = unsplitJID (Just $ clientUser clientState |
434 | , ch | 459 | , ch |
435 | ,Just $ clientResource clientState) | 460 | ,Just $ clientResource clientState) |
@@ -472,6 +497,7 @@ main = runResourceT $ do | |||
472 | , xmppSubscribeToRoster = \k -> return () | 497 | , xmppSubscribeToRoster = \k -> return () |
473 | , xmppDeliverMessage = deliverMessage state | 498 | , xmppDeliverMessage = deliverMessage state |
474 | , xmppInformClientPresence = informClientPresence state | 499 | , xmppInformClientPresence = informClientPresence state |
500 | , xmppInformPeerPresence = informPeerPresence state | ||
475 | , xmppAnswerProbe = answerProbe state | 501 | , xmppAnswerProbe = answerProbe state |
476 | } | 502 | } |
477 | liftIO $ do | 503 | liftIO $ do |