summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
authorJames Crayne <jim.crayne@gmail.com>2018-05-29 08:18:04 +0000
committerJames Crayne <jim.crayne@gmail.com>2018-05-29 08:18:04 +0000
commit4ce5feb72cdb452d0a6ba9cc326d541b292caedb (patch)
treece5102d88546473ae3a10af375bdcda0ff90344c /src/Network
parent49d97722c5ebc54b6e95c7499842b61afd23a9c4 (diff)
hooks to keep SessionView up to date
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/Tox/Crypto/Handlers.hs101
-rw-r--r--src/Network/Tox/Crypto/Transport.hs1
2 files changed, 97 insertions, 5 deletions
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs
index 602b14cc..fe620757 100644
--- a/src/Network/Tox/Crypto/Handlers.hs
+++ b/src/Network/Tox/Crypto/Handlers.hs
@@ -25,6 +25,7 @@ import qualified Data.PacketQueue as PQ
25 ;import Data.PacketQueue (PacketQueue) 25 ;import Data.PacketQueue (PacketQueue)
26import Data.Serialize as S 26import Data.Serialize as S
27import Data.Word 27import Data.Word
28import Data.Maybe
28import qualified Data.Word64Map as W64 29import qualified Data.Word64Map as W64
29import Data.Word64RangeMap 30import Data.Word64RangeMap
30import qualified Data.Set as Set 31import qualified Data.Set as Set
@@ -66,6 +67,9 @@ data SessionView = SessionView
66 { svNick :: TVar ByteString 67 { svNick :: TVar ByteString
67 , svStatus :: TVar UserStatus 68 , svStatus :: TVar UserStatus
68 , svStatusMsg :: TVar ByteString 69 , svStatusMsg :: TVar ByteString
70 , svTheirNick :: TVar ByteString
71 , svTheirStatus :: TVar UserStatus
72 , svTheirStatusMsg :: TVar ByteString
69 , svNoSpam :: TVar (Maybe NoSpam) 73 , svNoSpam :: TVar (Maybe NoSpam)
70 , svGroups :: TVar (Map.Map GroupChatId (Set.Set SockAddr)) 74 , svGroups :: TVar (Map.Map GroupChatId (Set.Set SockAddr))
71 75
@@ -193,6 +197,9 @@ newSessionsState crypto unrechook hooks = do
193 nick <- atomically $ newTVar B.empty 197 nick <- atomically $ newTVar B.empty
194 status <- atomically $ newTVar Online 198 status <- atomically $ newTVar Online
195 statusmsg <- atomically $ newTVar B.empty 199 statusmsg <- atomically $ newTVar B.empty
200 theirnick <- atomically $ newTVar B.empty
201 theirstatus <- atomically $ newTVar Online
202 theirstatusmsg <- atomically $ newTVar B.empty
196 nospam <- atomically $ newTVar Nothing 203 nospam <- atomically $ newTVar Nothing
197 grps <- atomically $ newTVar Map.empty 204 grps <- atomically $ newTVar Map.empty
198 pname <- getProgName 205 pname <- getProgName
@@ -214,6 +221,9 @@ newSessionsState crypto unrechook hooks = do
214 { svNick = nick 221 { svNick = nick
215 , svStatus = status 222 , svStatus = status
216 , svStatusMsg = statusmsg 223 , svStatusMsg = statusmsg
224 , svTheirNick = theirnick
225 , svTheirStatus = theirstatus
226 , svTheirStatusMsg = theirstatusmsg
217 , svNoSpam = nospam 227 , svNoSpam = nospam
218 , svGroups = grps 228 , svGroups = grps
219 , svCacheDir = cachedir 229 , svCacheDir = cachedir
@@ -652,28 +662,109 @@ allMsgTypes fDefault = A.listArray (minBound,maxBound) (0:knownMsgs)
652 , map (const 0) [ 200 .. 255 ] -- All lossy, exept the last 662 , map (const 0) [ 200 .. 255 ] -- All lossy, exept the last
653 ] 663 ]
654 664
655-- | handles nothing 665setNick :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String ())
666setNick crypto session nick = do
667 let Just (_,maxlen) = msgSizeParam NICKNAME
668 if B.length nick > maxlen
669 then return (Left $ "nickname must not exceed " ++ show maxlen ++ " bytes.")
670 else do
671 let viewVar = ncView session
672 atomically $ do
673 view <- readTVar viewVar
674 writeTVar (svNick view) nick
675 let nickPacket = error "todo"
676 return (Left "TODO: sendMessage crypto (NetCrypto nickPacket)")
677 -- return (Right ())
678
679setStatus :: TransportCrypto -> NetCryptoSession -> UserStatus -> IO (Either String ())
680setStatus crypto session status = do
681 let viewVar = ncView session
682 atomically $ do
683 view <- readTVar viewVar
684 writeTVar (svStatus view) status
685 let statusPacket = error "todo"
686 return (Left "TODO: sendMessage crypto (NetCrypto statusPacket)")
687
688setStatusMsg :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String ())
689setStatusMsg crypto session msg = do
690 let Just (_,maxlen) = msgSizeParam STATUSMESSAGE
691 if B.length msg > maxlen
692 then return (Left $ "status message must not exceed " ++ show maxlen ++ " bytes.")
693 else do
694 let viewVar = ncView session
695 atomically $ do
696 view <- readTVar viewVar
697 writeTVar (svStatusMsg view) msg
698 let statusMsgPacket = error "todo"
699 return (Left "TODO: sendMessage crypto (NetCrypto statusMsgPacket)")
700
701-- | handles nothings
656defaultCryptoDataHooks :: Map.Map MessageType [NetCryptoHook] 702defaultCryptoDataHooks :: Map.Map MessageType [NetCryptoHook]
657defaultCryptoDataHooks = Map.empty 703defaultCryptoDataHooks
704 = Map.fromList
705 [ (Msg USERSTATUS,[defaultUserStatusHook])
706 , (Msg NICKNAME, [defaultNicknameHook])
707 , (Msg STATUSMESSAGE, [defaultStatusMsgHook])
708 ]
709
710defaultUserStatusHook :: NetCryptoSession -> CryptoMessage -> IO (Maybe (CryptoMessage -> CryptoMessage))
711defaultUserStatusHook session cm@(TwoByte {msgID=USERSTATUS, msgByte=statusByte}) = do
712 let status = toEnum8 statusByte
713 viewVar = ncView session
714 atomically $ do
715 view <- readTVar viewVar
716 writeTVar (svTheirStatus view) status
717 hookHelper True (Msg USERSTATUS) session cm
718
719defaultNicknameHook :: NetCryptoSession -> CryptoMessage -> IO (Maybe (CryptoMessage -> CryptoMessage))
720defaultNicknameHook session cm@(UpToN {msgID=NICKNAME, msgBytes=nick}) = do
721 let viewVar = ncView session
722 atomically $ do
723 view <- readTVar viewVar
724 writeTVar (svTheirNick view) nick
725 hookHelper True (Msg NICKNAME) session cm
726
727defaultStatusMsgHook :: NetCryptoSession -> CryptoMessage -> IO (Maybe (CryptoMessage -> CryptoMessage))
728defaultStatusMsgHook session cm@(UpToN {msgID=STATUSMESSAGE, msgBytes=msg}) = do
729 let viewVar = ncView session
730 atomically $ do
731 view <- readTVar viewVar
732 writeTVar (svTheirStatusMsg view) msg
733 hookHelper True (Msg STATUSMESSAGE) session cm
658 734
659-- | updates ncLastNMsgs, and sends message to type-0 listeners 735-- | updates ncLastNMsgs, and sends message to type-0 listeners
660defaultUnRecHook :: MessageType -> NetCryptoHook 736defaultUnRecHook :: MessageType -> NetCryptoHook
661defaultUnRecHook typ session cm | any ($ typ) [isKillPacket, isOFFLINE] = atomically $ do 737defaultUnRecHook = hookHelper False
738
739hookHelper :: Bool -> MessageType -> NetCryptoHook
740hookHelper _ typ session cm | any ($ typ) [isKillPacket, isOFFLINE] = atomically $ do
662 tmchans <- map snd . IntMap.elems <$> readTVar (ncListeners session) 741 tmchans <- map snd . IntMap.elems <$> readTVar (ncListeners session)
663 forM_ tmchans $ \chan -> closeTMChan chan 742 forM_ tmchans $ \chan -> closeTMChan chan
664 return Nothing 743 return Nothing
665 744
666defaultUnRecHook typ session cm = do 745hookHelper handledFlg typ session cm = do
667 let msgQ = ncLastNMsgs session 746 let msgQ = ncLastNMsgs session
668 msgNumVar = ncMsgNumVar session 747 msgNumVar = ncMsgNumVar session
669 dropCntVar = ncDropCntVar session 748 dropCntVar = ncDropCntVar session
670 atomically $ do 749 atomically $ do
671 num <- readTVar msgNumVar 750 num <- readTVar msgNumVar
672 (wraps,offset) <- PQ.enqueue msgQ num (False,cm) 751 (wraps,offset) <- PQ.enqueue msgQ num (handledFlg,cm)
673 capacity <- PQ.getCapacity msgQ 752 capacity <- PQ.getCapacity msgQ
674 let dropped = wraps * capacity + offset 753 let dropped = wraps * capacity + offset
675 modifyTVar' msgNumVar (+1) 754 modifyTVar' msgNumVar (+1)
676 writeTVar dropCntVar dropped 755 writeTVar dropCntVar dropped
756 atomically $ do
757 idtmchans <- IntMap.assocs <$> readTVar (ncListeners session)
758 mbChans
759 <- forM idtmchans $ \(id,(typ,chan)) -> do
760 bClosed <- isClosedTMChan chan
761 if bClosed
762 then do
763 modifyTVar' (ncListeners session) (IntMap.delete id)
764 return Nothing
765 else return (if typ==0 then Just chan else Nothing)
766 forM_ (catMaybes mbChans) $ \chan -> do
767 writeTMChan chan cm
677 return Nothing 768 return Nothing
678 769
679-- | use to add a single hook to a specific session. 770-- | use to add a single hook to a specific session.
diff --git a/src/Network/Tox/Crypto/Transport.hs b/src/Network/Tox/Crypto/Transport.hs
index 70405a3e..40288502 100644
--- a/src/Network/Tox/Crypto/Transport.hs
+++ b/src/Network/Tox/Crypto/Transport.hs
@@ -53,6 +53,7 @@ module Network.Tox.Crypto.Transport
53 , fromEnum8 53 , fromEnum8
54 , fromEnum16 54 , fromEnum16
55 , toEnum8 55 , toEnum8
56 , msgSizeParam
56 ) where 57 ) where
57 58
58import Crypto.Tox 59import Crypto.Tox