summaryrefslogtreecommitdiff
path: root/Presence/XMPP.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r--Presence/XMPP.hs104
1 files changed, 74 insertions, 30 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index 8589999b..498106b9 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -30,6 +30,7 @@ import Data.Maybe (catMaybes)
30import Data.HList 30import Data.HList
31import Network.Socket ( Family ) 31import Network.Socket ( Family )
32import Control.Concurrent.STM 32import Control.Concurrent.STM
33import Control.Concurrent.STM.Delay
33import Data.Conduit 34import Data.Conduit
34import Data.Maybe 35import Data.Maybe
35import Data.ByteString (ByteString) 36import Data.ByteString (ByteString)
@@ -888,6 +889,7 @@ peerRejectsSubscription session stanza = do
888handlePeerIQGet :: (JabberPeerSession session, MonadIO m) => 889handlePeerIQGet :: (JabberPeerSession session, MonadIO m) =>
889 session -> XML.Event -> NestingXML o m () 890 session -> XML.Event -> NestingXML o m ()
890handlePeerIQGet session tag = do 891handlePeerIQGet session tag = do
892 -- TODO: Pings should not require an id field.
891 withJust (lookupAttrib "id" (tagAttrs tag)) $ \stanza_id -> do 893 withJust (lookupAttrib "id" (tagAttrs tag)) $ \stanza_id -> do
892 whenJust nextElement $ \child -> do 894 whenJust nextElement $ \child -> do
893 let unhandledGet req = do 895 let unhandledGet req = do
@@ -925,6 +927,8 @@ fromPeer session = doNestingXML $ do
925 whenJust nextElement $ \stanza -> do 927 whenJust nextElement $ \stanza -> do
926 stanza_lvl <- nesting 928 stanza_lvl <- nesting
927 929
930 liftIO $ sendPeerMessage session ActivityBump -- reset ping timer
931
928 let unhandledStanza = do 932 let unhandledStanza = do
929 xs <- gatherElement stanza Seq.empty 933 xs <- gatherElement stanza Seq.empty
930 prettyPrint "P: " (toList xs) 934 prettyPrint "P: " (toList xs)
@@ -983,6 +987,7 @@ instance CommandCache CachedMessages where
983 updateCache (OutBoundMessage msg) cache = cache -- TODO 987 updateCache (OutBoundMessage msg) cache = cache -- TODO
984 updateCache (Pong _ _ _) cache = cache -- pings are not cached 988 updateCache (Pong _ _ _) cache = cache -- pings are not cached
985 updateCache (Unsupported _ _ _ _) cache = cache -- error messages are not cached 989 updateCache (Unsupported _ _ _ _) cache = cache -- error messages are not cached
990 updateCache ActivityBump cache = cache
986 991
987instance ThreadChannelCommand OutBoundMessage where 992instance ThreadChannelCommand OutBoundMessage where
988 isQuitCommand Disconnect = True 993 isQuitCommand Disconnect = True
@@ -1007,14 +1012,23 @@ goodbyePeer =
1007 , EventEndDocument 1012 , EventEndDocument
1008 ] 1013 ]
1009 1014
1010presenceStanza sock fromjid tojid typ = do 1015peerJidTextLocal sock jid = do
1011 addr <- getSocketName sock 1016 addr <- getSocketName sock
1012 let jidstr jid = toStrict . L.decodeUtf8 1017 return . toStrict . L.decodeUtf8
1013 $ name jid <$++> "@" 1018 $ name jid <$++> "@"
1019 <?++> showPeer (RemotePeer addr)
1020 <++?> "/" <++$> resource jid
1021
1022peerJidTextRemote sock jid = do
1023 addr <- getPeerName sock
1024 return . toStrict . L.decodeUtf8
1025 $ name jid <$++> "@"
1014 <?++> showPeer (RemotePeer addr) 1026 <?++> showPeer (RemotePeer addr)
1015 <++?> "/" <++$> resource jid 1027 <++?> "/" <++$> resource jid
1016 from = jidstr fromjid 1028
1017 to = toStrict . L.decodeUtf8 1029presenceStanza sock fromjid tojid typ = do
1030 from <- peerJidTextLocal sock fromjid
1031 let to = toStrict . L.decodeUtf8
1018 $ name tojid <$++> "@" 1032 $ name tojid <$++> "@"
1019 <?++> showPeer (peer tojid) 1033 <?++> showPeer (peer tojid)
1020 return 1034 return
@@ -1074,8 +1088,8 @@ toPeer sock cache chan fail = do
1074 Just c -> (("id",[c]):) 1088 Just c -> (("id",[c]):)
1075 _ -> id ) 1089 _ -> id )
1076 [ attr "type" "result" 1090 [ attr "type" "result"
1077 , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) 1091 , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) -- TODO: should send numeric address
1078 , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) 1092 , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) -- TODO: should send numeric address
1079 ] 1093 ]
1080 , EventEndElement "{jabber:server}iq" 1094 , EventEndElement "{jabber:server}iq"
1081 ] 1095 ]
@@ -1090,8 +1104,8 @@ toPeer sock cache chan fail = do
1090 Just c -> (("id",[c]):) 1104 Just c -> (("id",[c]):)
1091 _ -> id ) 1105 _ -> id )
1092 [("type",[ContentText "error"]) 1106 [("type",[ContentText "error"])
1093 , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) 1107 , attr "to" (toStrict $ L.decodeUtf8 $ L.show to) -- TODO: should send numeric address
1094 , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) 1108 , attr "from" (toStrict $ L.decodeUtf8 $ L.show from) -- TODO: should send numeric address
1095 ] 1109 ]
1096 , EventBeginElement req [] 1110 , EventBeginElement req []
1097 , EventEndElement req 1111 , EventEndElement req
@@ -1120,28 +1134,58 @@ toPeer sock cache chan fail = do
1120 liftIO $ debugL "sending cached solicitation..." 1134 liftIO $ debugL "sending cached solicitation..."
1121 sendSolicitation from to 1135 sendSolicitation from to
1122 1136
1123 1137
1138 let five_sec = 5 * 1000000 :: Int
1139 ping_timer <- liftIO $ newDelay five_sec
1140 let bump = updateDelay ping_timer five_sec
1141
1124 fix $ \loop -> do 1142 fix $ \loop -> do
1125 event <- lift . atomically $ readTChan chan 1143 event <- lift . atomically $ orElse (Left `fmap` readTChan chan)
1126 case event of 1144 (Right `fmap` waitDelay ping_timer)
1127 OutBoundPresence p -> sendPresence p 1145 let sendPing () = do
1128 PresenceProbe from to -> do 1146 ping <- liftIO makePing
1129 liftIO $ debugL "sending live probe..." 1147 yield ping
1130 sendProbe from to 1148 loop
1131 Solicitation from to -> do 1149 where makePing = do
1132 liftIO $ debugL "sending live solicitation..." 1150 addr <- getSocketName sock
1133 sendSolicitation from to 1151 remote <- getPeerName sock
1134 Approval from to -> do 1152 let from = toStrict . L.decodeUtf8 . showPeer $ RemotePeer addr
1135 liftIO . debugL $ "sending approval "<++>bshow (from,to) 1153 to = toStrict . L.decodeUtf8 . showPeer $ RemotePeer remote
1136 sendApproval True from to 1154 mid = Just (ContentText "iduno")
1137 Rejection from to -> do 1155 return $
1138 liftIO . debugL $ "sending rejection "<++>bshow (from,to) 1156 [ EventBeginElement "{jabber:server}iq"
1139 sendApproval False from to 1157 $ (case mid of
1140 OutBoundMessage msg -> sendMessage msg 1158 Just c -> (("id",[c]):)
1141 Pong from to mid -> sendPong from to mid 1159 _ -> id )
1142 Unsupported from to mid tag -> sendUnsupported from to mid tag 1160 [("type",[ContentText "error"])
1143 Disconnect -> return () 1161 , attr "to" to
1144 when (not . isQuitCommand $ event) loop 1162 , attr "from" from
1163 ]
1164 , EventBeginElement "{urn:xmpp:ping}ping" []
1165 , EventEndElement "{urn:xmpp:ping}ping"
1166 , EventEndElement "{jabber:server}iq" ]
1167 chanEvent event = do
1168 case event of
1169 OutBoundPresence p -> sendPresence p
1170 PresenceProbe from to -> do
1171 liftIO $ debugL "sending live probe..."
1172 sendProbe from to
1173 Solicitation from to -> do
1174 liftIO $ debugL "sending live solicitation..."
1175 sendSolicitation from to
1176 Approval from to -> do
1177 liftIO . debugL $ "sending approval "<++>bshow (from,to)
1178 sendApproval True from to
1179 Rejection from to -> do
1180 liftIO . debugL $ "sending rejection "<++>bshow (from,to)
1181 sendApproval False from to
1182 OutBoundMessage msg -> sendMessage msg
1183 Pong from to mid -> sendPong from to mid
1184 Unsupported from to mid tag -> sendUnsupported from to mid tag
1185 Disconnect -> return ()
1186 ActivityBump -> liftIO bump
1187 when (not . isQuitCommand $ event) loop
1188 either chanEvent sendPing event
1145 return () 1189 return ()
1146 -- send goodbyePeer -- TODO: why does this cause an exception? 1190 -- send goodbyePeer -- TODO: why does this cause an exception?
1147 -- Text/XML/Stream/Render.hs:169:5-15: 1191 -- Text/XML/Stream/Render.hs:169:5-15: