|
|
|
@ -23,7 +23,7 @@ import Network.XMPP.Monad |
|
|
|
-- combination was alread handled |
|
|
|
-- combination was alread handled |
|
|
|
listenIQChan :: IQRequestType -- ^ type of IQs to receive (Get / Set) |
|
|
|
listenIQChan :: IQRequestType -- ^ type of IQs to receive (Get / Set) |
|
|
|
-> Text -- ^ namespace of the child element |
|
|
|
-> Text -- ^ namespace of the child element |
|
|
|
-> XMPPThread (Maybe ( TChan (IQRequest, TVar Bool))) |
|
|
|
-> XMPP (Maybe ( TChan (IQRequest, TVar Bool))) |
|
|
|
listenIQChan tp ns = do |
|
|
|
listenIQChan tp ns = do |
|
|
|
handlers <- asks iqHandlers |
|
|
|
handlers <- asks iqHandlers |
|
|
|
liftIO . atomically $ do |
|
|
|
liftIO . atomically $ do |
|
|
|
@ -39,7 +39,7 @@ listenIQChan tp ns = do |
|
|
|
-- | get the inbound stanza channel, duplicates from master if necessary |
|
|
|
-- | get the inbound stanza channel, duplicates from master if necessary |
|
|
|
-- please note that once duplicated it will keep filling up, call |
|
|
|
-- please note that once duplicated it will keep filling up, call |
|
|
|
-- 'dropMessageChan' to allow it to be garbage collected |
|
|
|
-- 'dropMessageChan' to allow it to be garbage collected |
|
|
|
getMessageChan :: XMPPThread (TChan (Either MessageError Message)) |
|
|
|
getMessageChan :: XMPP (TChan (Either MessageError Message)) |
|
|
|
getMessageChan = do |
|
|
|
getMessageChan = do |
|
|
|
mChR <- asks messagesRef |
|
|
|
mChR <- asks messagesRef |
|
|
|
mCh <- liftIO $ readIORef mChR |
|
|
|
mCh <- liftIO $ readIORef mChR |
|
|
|
@ -52,7 +52,7 @@ getMessageChan = do |
|
|
|
Just mCh' -> return mCh' |
|
|
|
Just mCh' -> return mCh' |
|
|
|
|
|
|
|
|
|
|
|
-- | see 'getMessageChan' |
|
|
|
-- | see 'getMessageChan' |
|
|
|
getPresenceChan :: XMPPThread (TChan (Either PresenceError Presence)) |
|
|
|
getPresenceChan :: XMPP (TChan (Either PresenceError Presence)) |
|
|
|
getPresenceChan = do |
|
|
|
getPresenceChan = do |
|
|
|
pChR <- asks presenceRef |
|
|
|
pChR <- asks presenceRef |
|
|
|
pCh <- liftIO $ readIORef pChR |
|
|
|
pCh <- liftIO $ readIORef pChR |
|
|
|
@ -66,40 +66,40 @@ getPresenceChan = do |
|
|
|
|
|
|
|
|
|
|
|
-- | Drop the local end of the inbound stanza channel |
|
|
|
-- | Drop the local end of the inbound stanza channel |
|
|
|
-- from our context so it can be GC-ed |
|
|
|
-- from our context so it can be GC-ed |
|
|
|
dropMessageChan :: XMPPThread () |
|
|
|
dropMessageChan :: XMPP () |
|
|
|
dropMessageChan = do |
|
|
|
dropMessageChan = do |
|
|
|
r <- asks messagesRef |
|
|
|
r <- asks messagesRef |
|
|
|
liftIO $ writeIORef r Nothing |
|
|
|
liftIO $ writeIORef r Nothing |
|
|
|
|
|
|
|
|
|
|
|
-- | see 'dropMessageChan' |
|
|
|
-- | see 'dropMessageChan' |
|
|
|
dropPresenceChan :: XMPPThread () |
|
|
|
dropPresenceChan :: XMPP () |
|
|
|
dropPresenceChan = do |
|
|
|
dropPresenceChan = do |
|
|
|
r <- asks presenceRef |
|
|
|
r <- asks presenceRef |
|
|
|
liftIO $ writeIORef r Nothing |
|
|
|
liftIO $ writeIORef r Nothing |
|
|
|
|
|
|
|
|
|
|
|
-- | Read an element from the inbound stanza channel, acquiring a copy |
|
|
|
-- | Read an element from the inbound stanza channel, acquiring a copy |
|
|
|
-- of the channel as necessary |
|
|
|
-- of the channel as necessary |
|
|
|
pullMessage :: XMPPThread (Either MessageError Message) |
|
|
|
pullMessage :: XMPP (Either MessageError Message) |
|
|
|
pullMessage = do |
|
|
|
pullMessage = do |
|
|
|
c <- getMessageChan |
|
|
|
c <- getMessageChan |
|
|
|
liftIO $ atomically $ readTChan c |
|
|
|
liftIO $ atomically $ readTChan c |
|
|
|
|
|
|
|
|
|
|
|
-- | Read an element from the inbound stanza channel, acquiring a copy |
|
|
|
-- | Read an element from the inbound stanza channel, acquiring a copy |
|
|
|
-- of the channel as necessary |
|
|
|
-- of the channel as necessary |
|
|
|
pullPresence :: XMPPThread (Either PresenceError Presence) |
|
|
|
pullPresence :: XMPP (Either PresenceError Presence) |
|
|
|
pullPresence = do |
|
|
|
pullPresence = do |
|
|
|
c <- getPresenceChan |
|
|
|
c <- getPresenceChan |
|
|
|
liftIO $ atomically $ readTChan c |
|
|
|
liftIO $ atomically $ readTChan c |
|
|
|
|
|
|
|
|
|
|
|
-- | Send a stanza to the server |
|
|
|
-- | Send a stanza to the server |
|
|
|
sendS :: Stanza -> XMPPThread () |
|
|
|
sendS :: Stanza -> XMPP () |
|
|
|
sendS a = do |
|
|
|
sendS a = do |
|
|
|
out <- asks outCh |
|
|
|
out <- asks outCh |
|
|
|
liftIO . atomically $ writeTChan out a |
|
|
|
liftIO . atomically $ writeTChan out a |
|
|
|
return () |
|
|
|
return () |
|
|
|
|
|
|
|
|
|
|
|
-- | Fork a new thread |
|
|
|
-- | Fork a new thread |
|
|
|
forkXMPP :: XMPPThread () -> XMPPThread ThreadId |
|
|
|
forkXMPP :: XMPP () -> XMPP ThreadId |
|
|
|
forkXMPP a = do |
|
|
|
forkXMPP a = do |
|
|
|
thread <- ask |
|
|
|
thread <- ask |
|
|
|
mCH' <- liftIO $ newIORef Nothing |
|
|
|
mCH' <- liftIO $ newIORef Nothing |
|
|
|
@ -110,7 +110,7 @@ forkXMPP a = do |
|
|
|
|
|
|
|
|
|
|
|
filterMessages :: (MessageError -> Bool) |
|
|
|
filterMessages :: (MessageError -> Bool) |
|
|
|
-> (Message -> Bool) |
|
|
|
-> (Message -> Bool) |
|
|
|
-> XMPPThread (Either MessageError Message) |
|
|
|
-> XMPP (Either MessageError Message) |
|
|
|
filterMessages f g = do |
|
|
|
filterMessages f g = do |
|
|
|
s <- pullMessage |
|
|
|
s <- pullMessage |
|
|
|
case s of |
|
|
|
case s of |
|
|
|
@ -119,7 +119,7 @@ filterMessages f g = do |
|
|
|
Right m | g m -> return $ Right m |
|
|
|
Right m | g m -> return $ Right m |
|
|
|
| otherwise -> filterMessages f g |
|
|
|
| otherwise -> filterMessages f g |
|
|
|
|
|
|
|
|
|
|
|
waitForMessage :: (Message -> Bool) -> XMPPThread Message |
|
|
|
waitForMessage :: (Message -> Bool) -> XMPP Message |
|
|
|
waitForMessage f = do |
|
|
|
waitForMessage f = do |
|
|
|
s <- pullMessage |
|
|
|
s <- pullMessage |
|
|
|
case s of |
|
|
|
case s of |
|
|
|
@ -127,7 +127,7 @@ waitForMessage f = do |
|
|
|
Right m | f m -> return m |
|
|
|
Right m | f m -> return m |
|
|
|
| otherwise -> waitForMessage f |
|
|
|
| otherwise -> waitForMessage f |
|
|
|
|
|
|
|
|
|
|
|
waitForMessageError :: (MessageError -> Bool) -> XMPPThread MessageError |
|
|
|
waitForMessageError :: (MessageError -> Bool) -> XMPP MessageError |
|
|
|
waitForMessageError f = do |
|
|
|
waitForMessageError f = do |
|
|
|
s <- pullMessage |
|
|
|
s <- pullMessage |
|
|
|
case s of |
|
|
|
case s of |
|
|
|
@ -135,7 +135,7 @@ waitForMessageError f = do |
|
|
|
Left m | f m -> return m |
|
|
|
Left m | f m -> return m |
|
|
|
| otherwise -> waitForMessageError f |
|
|
|
| otherwise -> waitForMessageError f |
|
|
|
|
|
|
|
|
|
|
|
waitForPresence :: (Presence -> Bool) -> XMPPThread Presence |
|
|
|
waitForPresence :: (Presence -> Bool) -> XMPP Presence |
|
|
|
waitForPresence f = do |
|
|
|
waitForPresence f = do |
|
|
|
s <- pullPresence |
|
|
|
s <- pullPresence |
|
|
|
case s of |
|
|
|
case s of |
|
|
|
@ -149,7 +149,7 @@ waitForPresence f = do |
|
|
|
-- The Action will run in the calling thread/ |
|
|
|
-- The Action will run in the calling thread/ |
|
|
|
-- NB: This will /not/ catch any exceptions. If you action dies, deadlocks |
|
|
|
-- NB: This will /not/ catch any exceptions. If you action dies, deadlocks |
|
|
|
-- or otherwisely exits abnormaly the XMPP session will be dead. |
|
|
|
-- or otherwisely exits abnormaly the XMPP session will be dead. |
|
|
|
withConnection :: XMPPConMonad a -> XMPPThread a |
|
|
|
withConnection :: XMPPConMonad a -> XMPP a |
|
|
|
withConnection a = do |
|
|
|
withConnection a = do |
|
|
|
readerId <- asks readerThread |
|
|
|
readerId <- asks readerThread |
|
|
|
stateRef <- asks conStateRef |
|
|
|
stateRef <- asks conStateRef |
|
|
|
@ -167,36 +167,36 @@ withConnection a = do |
|
|
|
return res |
|
|
|
return res |
|
|
|
|
|
|
|
|
|
|
|
-- | Send a presence Stanza |
|
|
|
-- | Send a presence Stanza |
|
|
|
sendPresence :: Presence -> XMPPThread () |
|
|
|
sendPresence :: Presence -> XMPP () |
|
|
|
sendPresence = sendS . PresenceS |
|
|
|
sendPresence = sendS . PresenceS |
|
|
|
|
|
|
|
|
|
|
|
-- | Send a Message Stanza |
|
|
|
-- | Send a Message Stanza |
|
|
|
sendMessage :: Message -> XMPPThread () |
|
|
|
sendMessage :: Message -> XMPP () |
|
|
|
sendMessage = sendS . MessageS |
|
|
|
sendMessage = sendS . MessageS |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
modifyHandlers :: (EventHandlers -> EventHandlers) -> XMPPThread () |
|
|
|
modifyHandlers :: (EventHandlers -> EventHandlers) -> XMPP () |
|
|
|
modifyHandlers f = do |
|
|
|
modifyHandlers f = do |
|
|
|
eh <- asks eventHandlers |
|
|
|
eh <- asks eventHandlers |
|
|
|
liftIO . atomically $ writeTVar eh . f =<< readTVar eh |
|
|
|
liftIO . atomically $ writeTVar eh . f =<< readTVar eh |
|
|
|
|
|
|
|
|
|
|
|
setSessionEndHandler :: XMPPThread () -> XMPPThread () |
|
|
|
setSessionEndHandler :: XMPP () -> XMPP () |
|
|
|
setSessionEndHandler eh = modifyHandlers (\s -> s{sessionEndHandler = eh}) |
|
|
|
setSessionEndHandler eh = modifyHandlers (\s -> s{sessionEndHandler = eh}) |
|
|
|
|
|
|
|
|
|
|
|
-- | run an event handler |
|
|
|
-- | run an event handler |
|
|
|
runHandler :: (EventHandlers -> XMPPThread a) -> XMPPThread a |
|
|
|
runHandler :: (EventHandlers -> XMPP a) -> XMPP a |
|
|
|
runHandler h = do |
|
|
|
runHandler h = do |
|
|
|
eh <- liftIO . atomically . readTVar =<< asks eventHandlers |
|
|
|
eh <- liftIO . atomically . readTVar =<< asks eventHandlers |
|
|
|
h eh |
|
|
|
h eh |
|
|
|
|
|
|
|
|
|
|
|
-- | End the current xmpp session |
|
|
|
-- | End the current xmpp session |
|
|
|
endSession :: XMPPThread () |
|
|
|
endSession :: XMPP () |
|
|
|
endSession = do -- TODO: This has to be idempotent (is it?) |
|
|
|
endSession = do -- TODO: This has to be idempotent (is it?) |
|
|
|
withConnection xmppKillConnection |
|
|
|
withConnection xmppKillConnection |
|
|
|
liftIO =<< asks stopThreads |
|
|
|
liftIO =<< asks stopThreads |
|
|
|
runHandler sessionEndHandler |
|
|
|
runHandler sessionEndHandler |
|
|
|
|
|
|
|
|
|
|
|
-- | Close the connection to the server |
|
|
|
-- | Close the connection to the server |
|
|
|
closeConnection :: XMPPThread () |
|
|
|
closeConnection :: XMPP () |
|
|
|
closeConnection = withConnection xmppKillConnection |
|
|
|
closeConnection = withConnection xmppKillConnection |
|
|
|
|
|
|
|
|
|
|
|
|