summaryrefslogtreecommitdiff
path: root/src/Network/Tox/Crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/Tox/Crypto')
-rw-r--r--src/Network/Tox/Crypto/Transport.hs85
1 files changed, 68 insertions, 17 deletions
diff --git a/src/Network/Tox/Crypto/Transport.hs b/src/Network/Tox/Crypto/Transport.hs
index f7fd0f7e..4b2e97ce 100644
--- a/src/Network/Tox/Crypto/Transport.hs
+++ b/src/Network/Tox/Crypto/Transport.hs
@@ -10,6 +10,7 @@ module Network.Tox.Crypto.Transport
10 , NetCrypto(..) 10 , NetCrypto(..)
11 , CryptoData(..) 11 , CryptoData(..)
12 , CryptoMessage(..) 12 , CryptoMessage(..)
13 , MessageName(..)
13 , CryptoPacket(..) 14 , CryptoPacket(..)
14 , HandshakeData(..) 15 , HandshakeData(..)
15 , Handshake(..) 16 , Handshake(..)
@@ -18,6 +19,7 @@ module Network.Tox.Crypto.Transport
18 , UserStatus(..) 19 , UserStatus(..)
19 , TypingStatus(..) 20 , TypingStatus(..)
20 , GroupChatId(..) 21 , GroupChatId(..)
22 , MessageType(..)
21 -- feild name classes 23 -- feild name classes
22 , HasGroupChatID(..) 24 , HasGroupChatID(..)
23 , HasGroupNumber(..) 25 , HasGroupNumber(..)
@@ -25,10 +27,14 @@ module Network.Tox.Crypto.Transport
25 , HasMessageNumber(..) 27 , HasMessageNumber(..)
26 , HasMessageName(..) 28 , HasMessageName(..)
27 , HasMessageData(..) 29 , HasMessageData(..)
30 , HasName(..)
31 , HasTitle(..)
32 , HasMessage(..)
33 , HasMessageType(..)
28 -- lenses 34 -- lenses
29 , userStatus, nick, statusMessage, typingStatus, message, action, groupChatID 35 , userStatus, nick, statusMessage, typingStatus, message, action, groupChatID
30 , groupNumber, groupNumberToJoin, peerNumber, messageNumber 36 , groupNumber, groupNumberToJoin, peerNumber, messageNumber
31 , messageName, messageData 37 , messageName, messageData, name, title, message, messageType
32 -- constructor 38 -- constructor
33 , msg 39 , msg
34 , leaveMsg 40 , leaveMsg
@@ -36,6 +42,7 @@ module Network.Tox.Crypto.Transport
36 -- utils 42 -- utils
37 , sizedN 43 , sizedN
38 , sizedAtLeastN 44 , sizedAtLeastN
45 , isIndirectGrpChat
39 ) where 46 ) where
40 47
41import Crypto.Tox 48import Crypto.Tox
@@ -192,14 +199,6 @@ statusMessage = lens getter setter
192 setter (UpToN STATUSMESSAGE _) nick = UpToN STATUSMESSAGE (T.encodeUtf8 . T.pack $ nick) 199 setter (UpToN STATUSMESSAGE _) nick = UpToN STATUSMESSAGE (T.encodeUtf8 . T.pack $ nick)
193 setter _ _ = erCompat "statusMessage" 200 setter _ _ = erCompat "statusMessage"
194 201
195message :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage)
196message = lens getter setter
197 where
198 getter (UpToN MESSAGE bstr) = T.unpack $ T.decodeUtf8 bstr
199 getter _ = erCompat "message"
200 setter (UpToN MESSAGE _) message = UpToN MESSAGE (T.encodeUtf8 . T.pack $ message)
201 setter _ _ = erCompat "message"
202
203action :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage) 202action :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage)
204action = lens getter setter 203action = lens getter setter
205 where 204 where
@@ -341,6 +340,7 @@ instance HasMessageNumber CryptoMessage where
341messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x) 340messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x)
342messageNumber = lens getMessageNumber setMessageNumber 341messageNumber = lens getMessageNumber setMessageNumber
343 342
343
344class HasMessageName x where 344class HasMessageName x where
345 getMessageName :: x -> MessageName 345 getMessageName :: x -> MessageName
346 setMessageName :: x -> MessageName -> x 346 setMessageName :: x -> MessageName -> x
@@ -363,6 +363,36 @@ instance HasMessageName CryptoMessage where
363messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x) 363messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x)
364messageName = lens getMessageName setMessageName 364messageName = lens getMessageName setMessageName
365 365
366data MessageType = Msg MessageID
367 | GrpMsg MessageName
368 deriving (Eq,Show)
369
370class HasMessageType x where
371 getMessageType :: x -> MessageType
372 setMessageType :: x -> MessageType -> x
373
374instance HasMessageType CryptoMessage where
375 getMessageType (OneByte mid) = Msg mid
376 getMessageType (TwoByte mid _) = Msg mid
377 getMessageType m@(UpToN mid _) | isIndirectGrpChat mid = GrpMsg (getMessageName m)
378 getMessageType (UpToN mid _) = Msg mid
379
380 setMessageType m@(UpToN mid _) (GrpMsg mname) | isIndirectGrpChat mid = setMessageName m mname
381 setMessageType (OneByte _ ) (GrpMsg mname) = setMessageName (UpToN MESSAGE_GROUPCHAT B.empty ) mname
382 setMessageType (TwoByte _ x) (GrpMsg mname) = setMessageName (UpToN MESSAGE_GROUPCHAT (B.singleton x)) mname
383 setMessageType (UpToN _ x) (GrpMsg mname) = setMessageName (UpToN MESSAGE_GROUPCHAT x) mname
384 setMessageType m (Msg mid) | Just (True,1) <- msgSizeParam mid = OneByte mid
385 setMessageType (OneByte mid0 ) (Msg mid) | Just (True,2) <- msgSizeParam mid = TwoByte mid 0
386 setMessageType (TwoByte mid0 x) (Msg mid) | Just (True,2) <- msgSizeParam mid = TwoByte mid x
387 setMessageType (UpToN mid0 x) (Msg mid) | Just (True,n) <- msgSizeParam mid = UpToN mid (sizedN n x)
388 setMessageType (OneByte mid0) (Msg mid) = UpToN mid B.empty
389 setMessageType (TwoByte mid0 x) (Msg mid) = UpToN mid (B.singleton x)
390 setMessageType (UpToN mid0 x) (Msg mid) = UpToN mid x
391
392-- | This lens should always succeed on CryptoMessage
393messageType :: (Functor f, HasMessageType x) => (MessageType -> f MessageType) -> (x -> f x)
394messageType = lens getMessageType setMessageType
395
366type MessageData = B.ByteString 396type MessageData = B.ByteString
367 397
368class HasMessageData x where 398class HasMessageData x where
@@ -388,17 +418,38 @@ class HasTitle x where
388 setTitle :: x -> Text -> x 418 setTitle :: x -> Text -> x
389 419
390instance HasTitle CryptoMessage where 420instance HasTitle CryptoMessage where
391 getTitle (UpToN (fromEnum -> 0x62) (sizedAtLeastN 4 -> B.splitAt 3 -> (_,B.uncons -> Just (0x0a,mdata)))) = decodeUtf8 mdata 421 getTitle (UpToN DIRECT_GROUPCHAT {-Ox62-} (sizedAtLeastN 4 -> B.splitAt 3 -> (_,B.uncons -> Just (0x0a,mdata)))) = decodeUtf8 mdata
422 getTitle (UpToN xE (sizedAtLeastN 4 -> B.splitAt 3 -> (_,B.uncons -> Just (toEnum . fromIntegral -> GroupchatTitleChange,mdata))))
423 | isIndirectGrpChat xE = decodeUtf8 mdata
392 getTitle _ = error "getTitle on CryptoMessage without title field." 424 getTitle _ = error "getTitle on CryptoMessage without title field."
393 425
394 -- If its not 426 setTitle (UpToN xE@DIRECT_GROUPCHAT {-0x62-} (sizedAtLeastN 4 -> B.splitAt 3 -> (bs,B.uncons -> Just (_,xs)))) messagedata
395 setTitle (UpToN xE@(fromEnum -> 0x62) (sizedAtLeastN 4 -> B.splitAt 3 -> (bs,B.uncons -> Just (_,xs)))) messagedata -- MESSAGE_GROUPCHAT
396 = UpToN xE (B.concat [bs,B.cons 0x0a (encodeUtf8 messagedata)]) 427 = UpToN xE (B.concat [bs,B.cons 0x0a (encodeUtf8 messagedata)])
428 setTitle (UpToN xE (sizedAtLeastN 4 -> B.splitAt 3 -> (bs,B.uncons -> Just (_,xs)))) title
429 | isIndirectGrpChat xE = UpToN xE (B.concat [bs,B.cons (fromIntegral $ fromEnum GroupchatTitleChange) (encodeUtf8 title)])
397 setTitle _ _ = error "setTitle on CryptoMessage without title field." 430 setTitle _ _ = error "setTitle on CryptoMessage without title field."
398 431
399title :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) 432title :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x)
400title = lens getTitle setTitle 433title = lens getTitle setTitle
401 434
435class HasMessage x where
436 getMessage :: x -> Text
437 setMessage :: x -> Text -> x
438
439instance HasMessage CryptoMessage where
440 getMessage (UpToN MESSAGE bstr) = T.decodeUtf8 bstr
441 getMessage (UpToN xE (sizedAtLeastN 9 -> B.splitAt 8 -> (_,B.uncons -> Just (mnameByte,mdata))))
442 | isIndirectGrpChat xE = decodeUtf8 mdata
443 getMessage _ = error "getMessage on CryptoMessage without message field."
444
445 setMessage (UpToN MESSAGE _) message = UpToN MESSAGE (T.encodeUtf8 $ message)
446 setMessage (UpToN xE (sizedAtLeastN 9 -> B.splitAt 8 -> (bs,B.uncons -> Just (mnameByte,xs)))) message
447 | isIndirectGrpChat xE = UpToN xE (B.concat [bs,B.cons (if mnameByte == 0 then 0x40 else mnameByte) (encodeUtf8 message)])
448 setMessage _ _ = error "setMessage on CryptoMessage without message field."
449
450message :: (Functor f, HasMessage x) => (Text -> f Text) -> (x -> f x)
451message = lens getMessage setMessage
452
402class HasName x where 453class HasName x where
403 getName :: x -> Text 454 getName :: x -> Text
404 setName :: x -> Text -> x 455 setName :: x -> Text -> x
@@ -406,12 +457,12 @@ class HasName x where
406 457
407instance HasName CryptoMessage where 458instance HasName CryptoMessage where
408 -- Only MESSAGE_GROUPCHAT:NameChange has Name field 459 -- Only MESSAGE_GROUPCHAT:NameChange has Name field
409 getName (UpToN xE (sizedAtLeastN 4 -> B.splitAt 3 -> (_,B.uncons -> Just (toEnum . fromIntegral -> NameChange,mdata)))) | isGroupChatMsg xE = decodeUtf8 mdata 460 getName (UpToN xE (sizedAtLeastN 4 -> B.splitAt 3 -> (_,B.uncons -> Just (toEnum . fromIntegral -> NameChange,mdata)))) | isIndirectGrpChat xE = decodeUtf8 mdata
410 getName _ = error "getName on CryptoMessage without name field." 461 getName _ = error "getName on CryptoMessage without name field."
411 462
412 -- If its not NameChange, this setter will set it to NameChange 463 -- If its not NameChange, this setter will set it to NameChange
413 setName (UpToN xE (sizedAtLeastN 4 -> B.splitAt 3 -> (bs,B.uncons -> Just (_,xs)))) name 464 setName (UpToN xE (sizedAtLeastN 4 -> B.splitAt 3 -> (bs,B.uncons -> Just (_,xs)))) name
414 | isGroupChatMsg xE = UpToN xE (B.concat [bs,B.cons (fromIntegral $ fromEnum NameChange) (encodeUtf8 name)]) 465 | isIndirectGrpChat xE = UpToN xE (B.concat [bs,B.cons (fromIntegral $ fromEnum NameChange) (encodeUtf8 name)])
415 setName _ _ = error "setName on CryptoMessage without name field." 466 setName _ _ = error "setName on CryptoMessage without name field."
416 467
417name :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) 468name :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x)
@@ -489,9 +540,9 @@ msgSizeParam MESSAGE_GROUPCHAT {-0x63-} = Nothing -- variable
489msgSizeParam LOSSY_GROUPCHAT {-0xC7-} = Nothing -- variable 540msgSizeParam LOSSY_GROUPCHAT {-0xC7-} = Nothing -- variable
490msgSizeParam _ = Nothing 541msgSizeParam _ = Nothing
491 542
492isGroupChatMsg MESSAGE_GROUPCHAT = True 543isIndirectGrpChat MESSAGE_GROUPCHAT = True
493isGroupChatMsg LOSSY_GROUPCHAT = True 544isIndirectGrpChat LOSSY_GROUPCHAT = True
494isGroupChatMsg _ = False 545isIndirectGrpChat _ = False
495 546
496-- TODO: Flesh this out. 547-- TODO: Flesh this out.
497data MessageID -- First byte indicates data 548data MessageID -- First byte indicates data