|
|
|
@ -8,14 +8,12 @@ module Network.Xmpp.Concurrent |
|
|
|
, module Network.Xmpp.Concurrent.Message |
|
|
|
, module Network.Xmpp.Concurrent.Message |
|
|
|
, module Network.Xmpp.Concurrent.Presence |
|
|
|
, module Network.Xmpp.Concurrent.Presence |
|
|
|
, module Network.Xmpp.Concurrent.IQ |
|
|
|
, module Network.Xmpp.Concurrent.IQ |
|
|
|
, toChans |
|
|
|
, StanzaHandler |
|
|
|
, newSession |
|
|
|
, newSession |
|
|
|
, writeWorker |
|
|
|
, writeWorker |
|
|
|
, session |
|
|
|
, session |
|
|
|
) where |
|
|
|
) where |
|
|
|
|
|
|
|
|
|
|
|
import Network.Xmpp.Concurrent.Monad |
|
|
|
|
|
|
|
import Network.Xmpp.Concurrent.Threads |
|
|
|
|
|
|
|
import Control.Applicative((<$>),(<*>)) |
|
|
|
import Control.Applicative((<$>),(<*>)) |
|
|
|
import Control.Concurrent |
|
|
|
import Control.Concurrent |
|
|
|
import Control.Concurrent.STM |
|
|
|
import Control.Concurrent.STM |
|
|
|
@ -23,25 +21,27 @@ import Control.Monad |
|
|
|
import qualified Data.ByteString as BS |
|
|
|
import qualified Data.ByteString as BS |
|
|
|
import Data.IORef |
|
|
|
import Data.IORef |
|
|
|
import qualified Data.Map as Map |
|
|
|
import qualified Data.Map as Map |
|
|
|
|
|
|
|
import Data.Maybe |
|
|
|
import Data.Maybe (fromMaybe) |
|
|
|
import Data.Maybe (fromMaybe) |
|
|
|
|
|
|
|
import Data.Text as Text |
|
|
|
import Data.XML.Types |
|
|
|
import Data.XML.Types |
|
|
|
|
|
|
|
import Network |
|
|
|
|
|
|
|
import qualified Network.TLS as TLS |
|
|
|
import Network.Xmpp.Concurrent.Basic |
|
|
|
import Network.Xmpp.Concurrent.Basic |
|
|
|
import Network.Xmpp.Concurrent.IQ |
|
|
|
import Network.Xmpp.Concurrent.IQ |
|
|
|
import Network.Xmpp.Concurrent.Message |
|
|
|
import Network.Xmpp.Concurrent.Message |
|
|
|
|
|
|
|
import Network.Xmpp.Concurrent.Monad |
|
|
|
import Network.Xmpp.Concurrent.Presence |
|
|
|
import Network.Xmpp.Concurrent.Presence |
|
|
|
import Network.Xmpp.Concurrent.Types |
|
|
|
|
|
|
|
import Network.Xmpp.Concurrent.Threads |
|
|
|
import Network.Xmpp.Concurrent.Threads |
|
|
|
|
|
|
|
import Network.Xmpp.Concurrent.Threads |
|
|
|
|
|
|
|
import Network.Xmpp.Concurrent.Types |
|
|
|
import Network.Xmpp.Marshal |
|
|
|
import Network.Xmpp.Marshal |
|
|
|
import Network.Xmpp.Types |
|
|
|
|
|
|
|
import Network |
|
|
|
|
|
|
|
import Data.Text as Text |
|
|
|
|
|
|
|
import Network.Xmpp.Tls |
|
|
|
|
|
|
|
import qualified Network.TLS as TLS |
|
|
|
|
|
|
|
import Network.Xmpp.Sasl |
|
|
|
import Network.Xmpp.Sasl |
|
|
|
import Network.Xmpp.Sasl.Mechanisms |
|
|
|
import Network.Xmpp.Sasl.Mechanisms |
|
|
|
import Network.Xmpp.Sasl.Types |
|
|
|
import Network.Xmpp.Sasl.Types |
|
|
|
import Data.Maybe |
|
|
|
|
|
|
|
import Network.Xmpp.Stream |
|
|
|
import Network.Xmpp.Stream |
|
|
|
|
|
|
|
import Network.Xmpp.Tls |
|
|
|
|
|
|
|
import Network.Xmpp.Types |
|
|
|
import Network.Xmpp.Utilities |
|
|
|
import Network.Xmpp.Utilities |
|
|
|
|
|
|
|
|
|
|
|
import Control.Monad.Error |
|
|
|
import Control.Monad.Error |
|
|
|
@ -49,18 +49,28 @@ import Data.Default |
|
|
|
import System.Log.Logger |
|
|
|
import System.Log.Logger |
|
|
|
import Control.Monad.State.Strict |
|
|
|
import Control.Monad.State.Strict |
|
|
|
|
|
|
|
|
|
|
|
toChans :: TChan Stanza |
|
|
|
runHandlers :: (TChan Stanza) -> [StanzaHandler] -> Stanza -> IO () |
|
|
|
-> TChan Stanza |
|
|
|
runHandlers _ [] _ = return () |
|
|
|
-> TVar IQHandlers |
|
|
|
runHandlers outC (h:hands) sta = do |
|
|
|
-> Stanza |
|
|
|
res <- h outC sta |
|
|
|
-> IO () |
|
|
|
case res of |
|
|
|
toChans stanzaC outC iqHands sta = atomically $ do |
|
|
|
True -> runHandlers outC hands sta |
|
|
|
writeTChan stanzaC sta |
|
|
|
False -> return () |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
toChan :: TChan Stanza -> StanzaHandler |
|
|
|
|
|
|
|
toChan stanzaC _ sta = do |
|
|
|
|
|
|
|
atomically $ writeTChan stanzaC sta |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handleIQ :: TVar IQHandlers |
|
|
|
|
|
|
|
-> StanzaHandler |
|
|
|
|
|
|
|
handleIQ iqHands outC sta = atomically $ do |
|
|
|
case sta of |
|
|
|
case sta of |
|
|
|
IQRequestS i -> handleIQRequest iqHands i |
|
|
|
IQRequestS i -> handleIQRequest iqHands i >> return False |
|
|
|
IQResultS i -> handleIQResponse iqHands (Right i) |
|
|
|
IQResultS i -> handleIQResponse iqHands (Right i) >> return False |
|
|
|
IQErrorS i -> handleIQResponse iqHands (Left i) |
|
|
|
IQErrorS i -> handleIQResponse iqHands (Left i) >> return False |
|
|
|
_ -> return () |
|
|
|
_ -> return True |
|
|
|
where |
|
|
|
where |
|
|
|
-- If the IQ request has a namespace, send it through the appropriate channel. |
|
|
|
-- If the IQ request has a namespace, send it through the appropriate channel. |
|
|
|
handleIQRequest :: TVar IQHandlers -> IQRequest -> STM () |
|
|
|
handleIQRequest :: TVar IQHandlers -> IQRequest -> STM () |
|
|
|
@ -96,7 +106,11 @@ newSession stream config = runErrorT $ do |
|
|
|
stanzaChan <- lift newTChanIO |
|
|
|
stanzaChan <- lift newTChanIO |
|
|
|
iqHandlers <- lift $ newTVarIO (Map.empty, Map.empty) |
|
|
|
iqHandlers <- lift $ newTVarIO (Map.empty, Map.empty) |
|
|
|
eh <- lift $ newTVarIO $ EventHandlers { connectionClosedHandler = sessionClosedHandler config } |
|
|
|
eh <- lift $ newTVarIO $ EventHandlers { connectionClosedHandler = sessionClosedHandler config } |
|
|
|
let stanzaHandler = toChans stanzaChan outC iqHandlers |
|
|
|
let stanzaHandler = runHandlers outC $ Prelude.concat [ [toChan stanzaChan] |
|
|
|
|
|
|
|
, extraStanzaHandlers |
|
|
|
|
|
|
|
config |
|
|
|
|
|
|
|
, [handleIQ iqHandlers] |
|
|
|
|
|
|
|
] |
|
|
|
(kill, wLock, streamState, readerThread) <- ErrorT $ startThreadsWith stanzaHandler eh stream |
|
|
|
(kill, wLock, streamState, readerThread) <- ErrorT $ startThreadsWith stanzaHandler eh stream |
|
|
|
writer <- lift $ forkIO $ writeWorker outC wLock |
|
|
|
writer <- lift $ forkIO $ writeWorker outC wLock |
|
|
|
return $ Session { stanzaCh = stanzaChan |
|
|
|
return $ Session { stanzaCh = stanzaChan |
|
|
|
|