diff options
Diffstat (limited to 'src/Network/Tox/Crypto')
-rw-r--r-- | src/Network/Tox/Crypto/Transport.hs | 830 |
1 files changed, 821 insertions, 9 deletions
diff --git a/src/Network/Tox/Crypto/Transport.hs b/src/Network/Tox/Crypto/Transport.hs index 2a0e4a38..efe491eb 100644 --- a/src/Network/Tox/Crypto/Transport.hs +++ b/src/Network/Tox/Crypto/Transport.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# LANGUAGE KindSignatures #-} | 1 | {-# LANGUAGE KindSignatures #-} |
2 | {-# LANGUAGE ViewPatterns #-} | ||
2 | module Network.Tox.Crypto.Transport | 3 | module Network.Tox.Crypto.Transport |
3 | ( parseNetCrypto | 4 | ( parseNetCrypto |
4 | , encodeNetCrypto | 5 | , encodeNetCrypto |
@@ -9,15 +10,42 @@ module Network.Tox.Crypto.Transport | |||
9 | , CryptoPacket(..) | 10 | , CryptoPacket(..) |
10 | , HandshakeData(..) | 11 | , HandshakeData(..) |
11 | , Handshake(..) | 12 | , Handshake(..) |
13 | , PeerInfo(..) | ||
14 | , MessageID(..) | ||
15 | , UserStatus(..) | ||
16 | , TypingStatus(..) | ||
17 | , GroupChatId(..) | ||
18 | -- feild name classes | ||
19 | , HasGroupChatID(..) | ||
20 | , HasGroupNumber(..) | ||
21 | , HasPeerNumber(..) | ||
22 | , HasMessageNumber(..) | ||
23 | , HasMessageName(..) | ||
24 | , HasMessageData(..) | ||
25 | -- lenses | ||
26 | , userStatus, nick, statusMessage, typingStatus, message, action, groupChatID | ||
27 | , groupNumber, groupNumberToJoin, peerNumber, messageNumber | ||
28 | , messageName, messageData | ||
29 | -- constructor | ||
30 | , msg | ||
31 | , leaveMsg | ||
32 | , peerQueryMsg | ||
33 | -- utils | ||
34 | , sizedN | ||
35 | , sizedAtLeastN | ||
12 | ) where | 36 | ) where |
13 | 37 | ||
14 | import Crypto.Tox | 38 | import Crypto.Tox |
15 | import Network.Tox.DHT.Transport (Cookie) | 39 | import Network.Tox.DHT.Transport (Cookie) |
16 | 40 | ||
17 | import Network.Socket | 41 | import Network.Socket |
18 | import Data.ByteString | 42 | import Data.ByteString as B |
19 | import Data.Word | 43 | import Data.Word |
20 | import Crypto.Hash | 44 | import Crypto.Hash |
45 | import Control.Lens | ||
46 | import Data.Text as T | ||
47 | import Data.Text.Encoding as T | ||
48 | import Data.Serialize as S | ||
21 | 49 | ||
22 | 50 | ||
23 | data NetCrypto | 51 | data NetCrypto |
@@ -58,17 +86,801 @@ data CryptoData = CryptoData | |||
58 | , bufferData :: CryptoMessage | 86 | , bufferData :: CryptoMessage |
59 | } | 87 | } |
60 | 88 | ||
89 | data UserStatus = Online | Away | Busy deriving (Show,Eq,Ord,Enum) | ||
90 | data TypingStatus = NotTyping | Typing deriving (Show,Eq,Ord,Enum) | ||
91 | |||
92 | data CryptoMessage | ||
93 | = OneByte { msgID :: MessageID } | ||
94 | | TwoByte { msgID :: MessageID, msgByte :: Word8 } | ||
95 | | UpToN { msgID :: MessageID, msgBytes :: ByteString } -- length < N | ||
96 | deriving (Eq,Show) | ||
97 | |||
98 | erCompat lens = error $ "Use of '" ++ lens ++ "' lens on incompatible CryptoMessage type" | ||
99 | |||
100 | typingStatus :: Functor f => (UserStatus -> f UserStatus)-> (CryptoMessage -> f CryptoMessage) | ||
101 | typingStatus = lens getter setter | ||
102 | where | ||
103 | getter (TwoByte TYPING status) = toEnum $ fromIntegral status | ||
104 | getter _ = erCompat "typingStatus" | ||
105 | setter (TwoByte TYPING _) status = TwoByte TYPING (fromIntegral . fromEnum $ status) | ||
106 | setter _ _ = erCompat "typingStatus" | ||
107 | |||
108 | userStatus :: Functor f => (UserStatus -> f UserStatus)-> (CryptoMessage -> f CryptoMessage) | ||
109 | userStatus = lens getter setter | ||
110 | where | ||
111 | getter (TwoByte USERSTATUS status) = toEnum $ fromIntegral status | ||
112 | getter _ = erCompat "userStatus" | ||
113 | setter (TwoByte USERSTATUS _) status = TwoByte USERSTATUS (fromIntegral . fromEnum $ status) | ||
114 | setter _ _ = erCompat "userStatus" | ||
115 | |||
116 | nick :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage) | ||
117 | nick = lens getter setter | ||
118 | where | ||
119 | getter (UpToN NICKNAME bstr) = T.unpack $ T.decodeUtf8 bstr | ||
120 | getter _ = erCompat "nick" | ||
121 | setter (UpToN NICKNAME _) nick = UpToN NICKNAME (T.encodeUtf8 . T.pack $ nick) | ||
122 | setter _ _ = erCompat "nick" | ||
123 | |||
124 | statusMessage :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage) | ||
125 | statusMessage = lens getter setter | ||
126 | where | ||
127 | getter (UpToN STATUSMESSAGE bstr) = T.unpack $ T.decodeUtf8 bstr | ||
128 | getter _ = erCompat "statusMessage" | ||
129 | setter (UpToN STATUSMESSAGE _) nick = UpToN STATUSMESSAGE (T.encodeUtf8 . T.pack $ nick) | ||
130 | setter _ _ = erCompat "statusMessage" | ||
131 | |||
132 | message :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage) | ||
133 | message = lens getter setter | ||
134 | where | ||
135 | getter (UpToN MESSAGE bstr) = T.unpack $ T.decodeUtf8 bstr | ||
136 | getter _ = erCompat "message" | ||
137 | setter (UpToN MESSAGE _) message = UpToN MESSAGE (T.encodeUtf8 . T.pack $ message) | ||
138 | setter _ _ = erCompat "message" | ||
139 | |||
140 | action :: Functor f => (String -> f String)-> (CryptoMessage -> f CryptoMessage) | ||
141 | action = lens getter setter | ||
142 | where | ||
143 | getter (UpToN ACTION bstr) = T.unpack $ T.decodeUtf8 bstr | ||
144 | getter _ = erCompat "action" | ||
145 | setter (UpToN ACTION _) action = UpToN ACTION (T.encodeUtf8 . T.pack $ action) | ||
146 | setter _ _ = erCompat "action" | ||
147 | |||
148 | newtype GroupChatId = GrpId ByteString -- 33 bytes | ||
149 | deriving (Show,Eq) | ||
150 | |||
151 | class HasGroupChatID x where | ||
152 | getGroupChatID :: x -> GroupChatId | ||
153 | setGroupChatID :: x -> GroupChatId -> x | ||
154 | |||
155 | sizedN n bs = if B.length bs < n then B.append bs (B.replicate (n - B.length bs) 0) | ||
156 | else B.take n bs | ||
157 | |||
158 | sizedAtLeastN n bs = if B.length bs < n then B.append bs (B.replicate (n - B.length bs) 0) | ||
159 | else bs | ||
160 | |||
161 | instance HasGroupChatID CryptoMessage where | ||
162 | -- Get | ||
163 | getGroupChatID (UpToN INVITE_GROUPCHAT payload) | ||
164 | = let (xs,ys) = B.splitAt 1 payload' | ||
165 | payload' = sizedN 38 payload | ||
166 | in case B.unpack xs of | ||
167 | [isResponse] | 0 <- isResponse -> GrpId (B.take 33 $ B.drop 2 ys) -- skip group number | ||
168 | [isResponse] | 1 <- isResponse -> GrpId (B.take 33 $ B.drop 4 ys) -- skip two group numbers | ||
169 | _ -> GrpId "" -- error "Unexpected value in INVITE_GROUPCHAT message" | ||
170 | |||
171 | getGroupChatID (UpToN ONLINE_PACKET payload) = GrpId (B.take 33 $ B.drop 2 (sizedN 35 payload)) | ||
172 | getGroupChatID _ = error "getGroupChatID on non-groupchat message." | ||
173 | |||
174 | -- Set | ||
175 | setGroupChatID msg@(UpToN INVITE_GROUPCHAT payload) (GrpId newid) | ||
176 | = let (xs,ys) = B.splitAt 1 payload' | ||
177 | payload' = sizedN 38 payload | ||
178 | in case B.unpack xs of | ||
179 | [isResponse] | 0 <- isResponse -> UpToN INVITE_GROUPCHAT (B.concat [xs, (B.take 2 ys), sizedN 33 newid]) -- keep group number | ||
180 | [isResponse] | 1 <- isResponse -> UpToN INVITE_GROUPCHAT (B.concat [xs, (B.take 4 ys), sizedN 33 newid]) -- keep two group numbers | ||
181 | _ -> msg -- unexpected condition, leave unchanged | ||
182 | |||
183 | setGroupChatID (UpToN ONLINE_PACKET payload) (GrpId newid) = UpToN ONLINE_PACKET (B.concat [B.take 2 payload, sizedN 33 newid]) | ||
184 | setGroupChatID _ _= error "setGroupChatID on non-groupchat message." | ||
185 | |||
186 | groupChatID :: (Functor f, HasGroupChatID x) => (GroupChatId -> f GroupChatId) -> (x -> f x) | ||
187 | groupChatID = lens getGroupChatID setGroupChatID | ||
188 | |||
189 | type GroupNumber = Word16 | ||
190 | type PeerNumber = Word16 | ||
191 | type MessageNumber = Word32 | ||
192 | |||
193 | class HasGroupNumber x where | ||
194 | getGroupNumber :: x -> GroupNumber | ||
195 | setGroupNumber :: x -> GroupNumber -> x | ||
196 | |||
197 | instance HasGroupNumber CryptoMessage where | ||
198 | getGroupNumber (UpToN INVITE_GROUPCHAT (sizedN 39 -> B.uncons -> Just (isResp,xs))) -- note isResp should be 0 or 1 | ||
199 | = let twobytes = B.take 2 xs | ||
200 | Right n = S.decode twobytes | ||
201 | in n | ||
202 | getGroupNumber (UpToN (fromEnum -> x) (sizedN 2 -> twobytes)) | x >= 0x61 && x <= 0x63 | ||
203 | = let Right n = S.decode twobytes in n | ||
204 | getGroupNumber (UpToN (fromEnum -> 0xC7) (sizedN 2 -> twobytes)) | ||
205 | = let Right n = S.decode twobytes in n | ||
206 | |||
207 | getGroupNumber _ = error "getGroupNumber on CryptoMessage without group number field." | ||
208 | |||
209 | setGroupNumber (UpToN INVITE_GROUPCHAT (sizedN 39 -> B.uncons -> Just (isResp,xs))) groupnum | ||
210 | = UpToN INVITE_GROUPCHAT (B.cons isResp (B.append (S.encode groupnum) (B.drop 2 xs))) | ||
211 | setGroupNumber (UpToN xE@(fromEnum -> x) (sizedAtLeastN 2 -> B.splitAt 2 -> (twobytes,xs))) groupnum | ||
212 | | x >= 0x61 && x <= 0x63 = UpToN xE (B.append (S.encode groupnum) xs) | ||
213 | | x == 0xC7 = UpToN xE (B.append (S.encode groupnum) xs) | ||
214 | setGroupNumber _ _ = error "setGroupNumber on CryptoMessage without group number field." | ||
215 | |||
216 | groupNumber :: (Functor f, HasGroupNumber x) => (Word16 -> f Word16) -> (x -> f x) | ||
217 | groupNumber = lens getGroupNumber setGroupNumber | ||
218 | |||
219 | class HasGroupNumberToJoin x where | ||
220 | getGroupNumberToJoin :: x -> GroupNumber | ||
221 | setGroupNumberToJoin :: x -> GroupNumber -> x | ||
222 | |||
223 | instance HasGroupNumberToJoin CryptoMessage where | ||
224 | getGroupNumberToJoin (UpToN INVITE_GROUPCHAT (sizedN 39 -> B.uncons -> Just (1,xs))) -- only response has to-join | ||
225 | = let twobytes = B.take 2 (B.drop 2 xs) -- skip group number (local) | ||
226 | Right n = S.decode twobytes | ||
227 | in n | ||
228 | getGroupNumberToJoin _ = error "getGroupNumberToJoin on CryptoMessage without group number (to join) field." | ||
229 | setGroupNumberToJoin (UpToN INVITE_GROUPCHAT (sizedN 39 -> B.uncons -> Just (1,xs))) groupnum | ||
230 | = let (a,b) = B.splitAt 2 xs | ||
231 | (twoBytes,c) = B.splitAt 2 b | ||
232 | twoBytes' = S.encode groupnum | ||
233 | in UpToN INVITE_GROUPCHAT (B.cons 1 (B.concat [a,twoBytes',c])) | ||
234 | setGroupNumberToJoin _ _ = error "setGroupNumberToJoin on CryptoMessage without group number (to join) field." | ||
235 | |||
236 | groupNumberToJoin :: (Functor f, HasGroupNumberToJoin x) => (GroupNumber -> f GroupNumber) -> (x -> f x) | ||
237 | groupNumberToJoin = lens getGroupNumberToJoin setGroupNumberToJoin | ||
238 | |||
239 | class HasPeerNumber x where | ||
240 | getPeerNumber :: x -> PeerNumber | ||
241 | setPeerNumber :: x -> PeerNumber -> x | ||
242 | |||
243 | instance HasPeerNumber CryptoMessage where | ||
244 | getPeerNumber (UpToN (fromEnum -> 0x63) (sizedN 4 -> B.splitAt 2 -> (grpnum,twobytes))) | ||
245 | = let Right n = S.decode twobytes in n | ||
246 | getPeerNumber (UpToN (fromEnum -> 0xC7) (sizedN 4 -> B.splitAt 2 -> (grpnum,twobytes))) | ||
247 | = let Right n = S.decode twobytes in n | ||
248 | getPeerNumber _ = error "getPeerNumber on CryptoMessage without peer number field." | ||
249 | |||
250 | setPeerNumber (UpToN xE@(fromEnum -> 0x63) (sizedAtLeastN 4 -> B.splitAt 2 -> (gnum,xs))) peernum | ||
251 | = UpToN xE (B.concat [gnum,S.encode peernum, B.drop 2 xs]) | ||
252 | setPeerNumber (UpToN xE@(fromEnum -> 0xC7) (sizedAtLeastN 4 -> B.splitAt 2 -> (gnum,xs))) peernum | ||
253 | = UpToN xE (B.concat [gnum,S.encode peernum, B.drop 2 xs]) | ||
254 | setPeerNumber _ _ = error "setPeerNumber on CryptoMessage without peer number field." | ||
255 | |||
256 | peerNumber :: (Functor f, HasPeerNumber x) => (Word16 -> f Word16) -> (x -> f x) | ||
257 | peerNumber = lens getPeerNumber setPeerNumber | ||
258 | |||
259 | class HasMessageNumber x where | ||
260 | getMessageNumber :: x -> MessageNumber | ||
261 | setMessageNumber :: x -> MessageNumber -> x | ||
262 | |||
263 | instance HasMessageNumber CryptoMessage where | ||
264 | getMessageNumber (UpToN (fromEnum -> 0x63) (sizedN 8 -> B.splitAt 4 -> (_,fourbytes))) | ||
265 | = let Right n = S.decode fourbytes in n | ||
266 | getMessageNumber (UpToN (fromEnum -> 0xC7) (sizedN 8 -> B.splitAt 4 -> (_,fourbytes))) | ||
267 | = let Right n = S.decode fourbytes in n | ||
268 | getMessageNumber _ = error "getMessageNumber on CryptoMessage without message number field." | ||
269 | |||
270 | setMessageNumber (UpToN xE@(fromEnum -> 0x63) (sizedAtLeastN 8 -> B.splitAt 4 -> (bs,xs))) messagenum | ||
271 | = UpToN xE (B.concat [bs,S.encode messagenum, B.drop 4 xs]) | ||
272 | setMessageNumber (UpToN xE@(fromEnum -> 0xC7) (sizedAtLeastN 8 -> B.splitAt 4 -> (bs,xs))) messagenum | ||
273 | = UpToN xE (B.concat [bs,S.encode messagenum, B.drop 4 xs]) | ||
274 | setMessageNumber _ _ = error "setMessageNumber on CryptoMessage without message number field." | ||
275 | |||
276 | messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x) | ||
277 | messageNumber = lens getMessageNumber setMessageNumber | ||
278 | |||
279 | class HasMessageName x where | ||
280 | getMessageName :: x -> MessageName | ||
281 | setMessageName :: x -> MessageName -> x | ||
282 | |||
283 | instance HasMessageName CryptoMessage where | ||
284 | getMessageName (UpToN (fromEnum -> 0x63) (sizedN 9 -> B.splitAt 8 -> (_,onebyte))) | ||
285 | = let [n] = B.unpack onebyte | ||
286 | in toEnum . fromIntegral $ n | ||
287 | getMessageName (UpToN (fromEnum -> 0xC7) (sizedN 9 -> B.splitAt 8 -> (_,onebyte))) | ||
288 | = let [n] = B.unpack onebyte | ||
289 | in toEnum . fromIntegral $ n | ||
290 | getMessageName _ = error "getMessageName on CryptoMessage without message number field." | ||
291 | |||
292 | setMessageName (UpToN xE@(fromEnum -> 0x63) (sizedAtLeastN 9 -> B.splitAt 8 -> (bs,xs))) messagename | ||
293 | = UpToN xE (B.concat [bs,B.cons (fromIntegral $ fromEnum messagename) (B.drop 1 xs)]) | ||
294 | setMessageName (UpToN xE@(fromEnum -> 0xC7) (sizedAtLeastN 9 -> B.splitAt 8 -> (bs,xs))) messagename | ||
295 | = UpToN xE (B.concat [bs,B.cons (fromIntegral $ fromEnum messagename) (B.drop 1 xs)]) | ||
296 | setMessageName _ _ = error "setMessageName on CryptoMessage without message number field." | ||
297 | |||
298 | messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x) | ||
299 | messageName = lens getMessageName setMessageName | ||
300 | |||
301 | type MessageData = B.ByteString | ||
302 | |||
303 | class HasMessageData x where | ||
304 | getMessageData :: x -> MessageData | ||
305 | setMessageData :: x -> MessageData -> x | ||
306 | |||
307 | instance HasMessageData CryptoMessage where | ||
308 | getMessageData (UpToN (fromEnum -> 0x63) (sizedAtLeastN 9 -> B.splitAt 9 -> (_,mdata))) = mdata | ||
309 | getMessageData (UpToN (fromEnum -> 0xC7) (sizedAtLeastN 9 -> B.splitAt 9 -> (_,mdata))) = mdata | ||
310 | getMessageData _ = error "getMessageData on CryptoMessage without message number field." | ||
311 | |||
312 | setMessageData (UpToN xE@(fromEnum -> 0x63) (sizedAtLeastN 9 -> B.splitAt 9 -> (bs,xs))) messagedata -- MESSAGE_GROUPCHAT | ||
313 | = UpToN xE (B.concat [bs,messagedata]) | ||
314 | setMessageData (UpToN xE@(fromEnum -> 0xC7) (sizedAtLeastN 9 -> B.splitAt 9 -> (bs,xs))) messagedata -- LOSSY_GROUPCHAT | ||
315 | = UpToN xE (B.concat [bs,messagedata]) | ||
316 | setMessageData _ _ = error "setMessageData on CryptoMessage without message number field." | ||
317 | |||
318 | messageData :: (Functor f, HasMessageData x) => (MessageData -> f MessageData) -> (x -> f x) | ||
319 | messageData = lens getMessageData setMessageData | ||
320 | |||
321 | data PeerInfo | ||
322 | = PeerInfo | ||
323 | { piPeerNum :: PeerNumber | ||
324 | , piUserKey :: PublicKey | ||
325 | , piDHTKey :: PublicKey | ||
326 | , piName :: ByteString -- byte-prefix for length | ||
327 | } deriving (Eq,Show) | ||
328 | |||
329 | |||
330 | -- | | ||
331 | -- default constructor, handy for formations such as: | ||
332 | -- | ||
333 | -- > userStatus .~ Busy $ msg USERSTATUS | ||
334 | -- | ||
335 | msg mid | Just (True,0) <- msgSizeParam mid = OneByte mid | ||
336 | msg mid | Just (True,1) <- msgSizeParam mid = TwoByte mid 0 | ||
337 | msg mid | Just (False,_) <- msgSizeParam mid = UpToN mid B.empty | ||
338 | |||
339 | leaveMsg groupnum = UpToN DIRECT_GROUPCHAT (B.snoc (S.encode groupnum) 0x01) | ||
340 | peerQueryMsg groupnum = UpToN DIRECT_GROUPCHAT (B.snoc (S.encode groupnum) 0x08) | ||
341 | |||
342 | |||
343 | -- | Returns if the given message is of fixed(OneByte/TwoByte) size, as well as | ||
344 | -- the maximum allowed size for the message Payload (message minus id) | ||
345 | -- Or Nothing if unknown/unimplemented. | ||
346 | msgSizeParam :: MessageID -> Maybe (Bool,Int) | ||
347 | msgSizeParam ONLINE = Just (True,0) | ||
348 | msgSizeParam OFFLINE = Just (True,0) | ||
349 | msgSizeParam USERSTATUS = Just (True,1) | ||
350 | msgSizeParam TYPING = Just (True,1) | ||
351 | msgSizeParam NICKNAME = Just (False,128) | ||
352 | msgSizeParam STATUSMESSAGE = Just (False,1007) | ||
353 | msgSizeParam MESSAGE = Just (False,1372) | ||
354 | msgSizeParam ACTION = Just (False,1372) | ||
355 | msgSizeParam FILE_DATA = Just (False,1372)-- up to 1373 | ||
356 | msgSizeParam FILE_SENDREQUEST = Just (False,300) -- 1+1+4+8+32+max255 = up to 301 | ||
357 | msgSizeParam FILE_CONTROL = Just (False,7) -- 8 bytes if seek, otherwise 4 | ||
358 | msgSizeParam INVITE_GROUPCHAT = Just (False,38) | ||
359 | msgSizeParam ONLINE_PACKET = Just (True,35) | ||
360 | msgSizeParam DIRECT_GROUPCHAT = Nothing -- 1+2+1 thus Just (True,3) leave & peer-query, but variable in response packets | ||
361 | msgSizeParam MESSAGE_GROUPCHAT = Nothing -- variable | ||
362 | msgSizeParam LOSSY_GROUPCHAT = Nothing -- variable | ||
363 | msgSizeParam _ = Nothing | ||
364 | |||
61 | -- TODO: Flesh this out. | 365 | -- TODO: Flesh this out. |
62 | data CryptoMessage -- First byte indicates data | 366 | data MessageID -- First byte indicates data |
63 | = Padding -- ^ 0 padding (skipped until we hit a non zero (data id) byte) | 367 | = Padding -- ^ 0 padding (skipped until we hit a non zero (data id) byte) |
64 | | PacketRequest -- ^ 1 packet request packet (lossy packet) | 368 | | PacketRequest -- ^ 1 packet request packet (lossy packet) |
65 | | KillPacket -- ^ 2 connection kill packet (lossy packet) | 369 | | KillPacket -- ^ 2 connection kill packet (lossy packet) |
66 | | UnspecifiedPacket -- ^ 3+ unspecified | 370 | | UnspecifiedPacket003 -- ^ 3+ unspecified |
67 | | MessengerLossless -- ^ 16+ reserved for Messenger usage (lossless packets) | 371 | | UnspecifiedPacket004 |
68 | | MessengerLossy -- ^ 192+ reserved for Messenger usage (lossy packets) | 372 | | UnspecifiedPacket005 |
69 | | Messenger255 -- ^ 255 reserved for Messenger usage (lossless packet) | 373 | | UnspecifiedPacket006 |
374 | | UnspecifiedPacket007 | ||
375 | | UnspecifiedPacket008 | ||
376 | | UnspecifiedPacket009 | ||
377 | | UnspecifiedPacket010 | ||
378 | | UnspecifiedPacket011 | ||
379 | | UnspecifiedPacket012 | ||
380 | | UnspecifiedPacket013 | ||
381 | | UnspecifiedPacket014 | ||
382 | | UnspecifiedPacket015 | ||
383 | | MessengerLossless016 -- ^ 16+ reserved for Messenger usage (lossless packets) | ||
384 | | MessengerLossless017 | ||
385 | | MessengerLossless018 | ||
386 | | MessengerLossless019 | ||
387 | | MessengerLossless020 | ||
388 | | MessengerLossless021 | ||
389 | | MessengerLossless022 | ||
390 | | MessengerLossless023 | ||
391 | | ONLINE -- 1 byte | ||
392 | | OFFLINE -- 1 byte | ||
393 | | MessengerLossless026 | ||
394 | | MessengerLossless027 | ||
395 | | MessengerLossless028 | ||
396 | | MessengerLossless029 | ||
397 | | MessengerLossless030 | ||
398 | | MessengerLossless031 | ||
399 | | MessengerLossless032 | ||
400 | | MessengerLossless033 | ||
401 | | MessengerLossless034 | ||
402 | | MessengerLossless035 | ||
403 | | MessengerLossless036 | ||
404 | | MessengerLossless037 | ||
405 | | MessengerLossless038 | ||
406 | | MessengerLossless039 | ||
407 | | MessengerLossless040 | ||
408 | | MessengerLossless041 | ||
409 | | MessengerLossless042 | ||
410 | | MessengerLossless043 | ||
411 | | MessengerLossless044 | ||
412 | | MessengerLossless045 | ||
413 | | MessengerLossless046 | ||
414 | | MessengerLossless047 | ||
415 | | NICKNAME -- up to 129 bytes | ||
416 | | STATUSMESSAGE -- up to 1008 bytes | ||
417 | | USERSTATUS -- 2 bytes | ||
418 | | TYPING -- 2 bytes | ||
419 | | MessengerLossless052 | ||
420 | | MessengerLossless053 | ||
421 | | MessengerLossless054 | ||
422 | | MessengerLossless055 | ||
423 | | MessengerLossless056 | ||
424 | | MessengerLossless057 | ||
425 | | MessengerLossless058 | ||
426 | | MessengerLossless059 | ||
427 | | MessengerLossless060 | ||
428 | | MessengerLossless061 | ||
429 | | MessengerLossless062 | ||
430 | | MessengerLossless063 | ||
431 | | MESSAGE -- up to 1373 bytes | ||
432 | | ACTION -- up to 1373 bytes | ||
433 | | MessengerLossless066 | ||
434 | | MessengerLossless067 | ||
435 | | MessengerLossless068 | ||
436 | | MSI | ||
437 | | MessengerLossless070 | ||
438 | | MessengerLossless071 | ||
439 | | MessengerLossless072 | ||
440 | | MessengerLossless073 | ||
441 | | MessengerLossless074 | ||
442 | | MessengerLossless075 | ||
443 | | MessengerLossless076 | ||
444 | | MessengerLossless077 | ||
445 | | MessengerLossless078 | ||
446 | | MessengerLossless079 | ||
447 | | FILE_SENDREQUEST -- 1+1+4+8+32+max255 = up to 301 | ||
448 | | FILE_CONTROL -- 8 bytes if seek, otherwise 4 | ||
449 | | FILE_DATA -- up to 1373 | ||
450 | | MessengerLossless083 | ||
451 | | MessengerLossless084 | ||
452 | | MessengerLossless085 | ||
453 | | MessengerLossless086 | ||
454 | | MessengerLossless087 | ||
455 | | MessengerLossless088 | ||
456 | | MessengerLossless089 | ||
457 | | MessengerLossless090 | ||
458 | | MessengerLossless091 | ||
459 | | MessengerLossless092 | ||
460 | | MessengerLossless093 | ||
461 | | MessengerLossless094 | ||
462 | | MessengerLossless095 | ||
463 | | INVITE_GROUPCHAT | ||
464 | | ONLINE_PACKET | ||
465 | | DIRECT_GROUPCHAT | ||
466 | | MESSAGE_GROUPCHAT | ||
467 | | MessengerLossless100 | ||
468 | | MessengerLossless101 | ||
469 | | MessengerLossless102 | ||
470 | | MessengerLossless103 | ||
471 | | MessengerLossless104 | ||
472 | | MessengerLossless105 | ||
473 | | MessengerLossless106 | ||
474 | | MessengerLossless107 | ||
475 | | MessengerLossless108 | ||
476 | | MessengerLossless109 | ||
477 | | MessengerLossless110 | ||
478 | | MessengerLossless111 | ||
479 | | MessengerLossless112 | ||
480 | | MessengerLossless113 | ||
481 | | MessengerLossless114 | ||
482 | | MessengerLossless115 | ||
483 | | MessengerLossless116 | ||
484 | | MessengerLossless117 | ||
485 | | MessengerLossless118 | ||
486 | | MessengerLossless119 | ||
487 | | MessengerLossless120 | ||
488 | | MessengerLossless121 | ||
489 | | MessengerLossless122 | ||
490 | | MessengerLossless123 | ||
491 | | MessengerLossless124 | ||
492 | | MessengerLossless125 | ||
493 | | MessengerLossless126 | ||
494 | | MessengerLossless127 | ||
495 | | MessengerLossless128 | ||
496 | | MessengerLossless129 | ||
497 | | MessengerLossless130 | ||
498 | | MessengerLossless131 | ||
499 | | MessengerLossless132 | ||
500 | | MessengerLossless133 | ||
501 | | MessengerLossless134 | ||
502 | | MessengerLossless135 | ||
503 | | MessengerLossless136 | ||
504 | | MessengerLossless137 | ||
505 | | MessengerLossless138 | ||
506 | | MessengerLossless139 | ||
507 | | MessengerLossless140 | ||
508 | | MessengerLossless141 | ||
509 | | MessengerLossless142 | ||
510 | | MessengerLossless143 | ||
511 | | MessengerLossless144 | ||
512 | | MessengerLossless145 | ||
513 | | MessengerLossless146 | ||
514 | | MessengerLossless147 | ||
515 | | MessengerLossless148 | ||
516 | | MessengerLossless149 | ||
517 | | MessengerLossless150 | ||
518 | | MessengerLossless151 | ||
519 | | MessengerLossless152 | ||
520 | | MessengerLossless153 | ||
521 | | MessengerLossless154 | ||
522 | | MessengerLossless155 | ||
523 | | MessengerLossless156 | ||
524 | | MessengerLossless157 | ||
525 | | MessengerLossless158 | ||
526 | | MessengerLossless159 | ||
527 | | MessengerLossless160 | ||
528 | | MessengerLossless161 | ||
529 | | MessengerLossless162 | ||
530 | | MessengerLossless163 | ||
531 | | MessengerLossless164 | ||
532 | | MessengerLossless165 | ||
533 | | MessengerLossless166 | ||
534 | | MessengerLossless167 | ||
535 | | MessengerLossless168 | ||
536 | | MessengerLossless169 | ||
537 | | MessengerLossless170 | ||
538 | | MessengerLossless171 | ||
539 | | MessengerLossless172 | ||
540 | | MessengerLossless173 | ||
541 | | MessengerLossless174 | ||
542 | | MessengerLossless175 | ||
543 | | MessengerLossless176 | ||
544 | | MessengerLossless177 | ||
545 | | MessengerLossless178 | ||
546 | | MessengerLossless179 | ||
547 | | MessengerLossless180 | ||
548 | | MessengerLossless181 | ||
549 | | MessengerLossless182 | ||
550 | | MessengerLossless183 | ||
551 | | MessengerLossless184 | ||
552 | | MessengerLossless185 | ||
553 | | MessengerLossless186 | ||
554 | | MessengerLossless187 | ||
555 | | MessengerLossless188 | ||
556 | | MessengerLossless189 | ||
557 | | MessengerLossless190 | ||
558 | | MessengerLossless191 | ||
559 | | MessengerLossy192 -- ^ 192+ reserved for Messenger usage (lossy packets) | ||
560 | | MessengerLossy193 | ||
561 | | MessengerLossy194 | ||
562 | | MessengerLossy195 | ||
563 | | MessengerLossy196 | ||
564 | | MessengerLossy197 | ||
565 | | MessengerLossy198 | ||
566 | | LOSSY_GROUPCHAT | ||
567 | | MessengerLossy200 | ||
568 | | MessengerLossy201 | ||
569 | | MessengerLossy202 | ||
570 | | MessengerLossy203 | ||
571 | | MessengerLossy204 | ||
572 | | MessengerLossy205 | ||
573 | | MessengerLossy206 | ||
574 | | MessengerLossy207 | ||
575 | | MessengerLossy208 | ||
576 | | MessengerLossy209 | ||
577 | | MessengerLossy210 | ||
578 | | MessengerLossy211 | ||
579 | | MessengerLossy212 | ||
580 | | MessengerLossy213 | ||
581 | | MessengerLossy214 | ||
582 | | MessengerLossy215 | ||
583 | | MessengerLossy216 | ||
584 | | MessengerLossy217 | ||
585 | | MessengerLossy218 | ||
586 | | MessengerLossy219 | ||
587 | | MessengerLossy220 | ||
588 | | MessengerLossy221 | ||
589 | | MessengerLossy222 | ||
590 | | MessengerLossy223 | ||
591 | | MessengerLossy224 | ||
592 | | MessengerLossy225 | ||
593 | | MessengerLossy226 | ||
594 | | MessengerLossy227 | ||
595 | | MessengerLossy228 | ||
596 | | MessengerLossy229 | ||
597 | | MessengerLossy230 | ||
598 | | MessengerLossy231 | ||
599 | | MessengerLossy232 | ||
600 | | MessengerLossy233 | ||
601 | | MessengerLossy234 | ||
602 | | MessengerLossy235 | ||
603 | | MessengerLossy236 | ||
604 | | MessengerLossy237 | ||
605 | | MessengerLossy238 | ||
606 | | MessengerLossy239 | ||
607 | | MessengerLossy240 | ||
608 | | MessengerLossy241 | ||
609 | | MessengerLossy242 | ||
610 | | MessengerLossy243 | ||
611 | | MessengerLossy244 | ||
612 | | MessengerLossy245 | ||
613 | | MessengerLossy246 | ||
614 | | MessengerLossy247 | ||
615 | | MessengerLossy248 | ||
616 | | MessengerLossy249 | ||
617 | | MessengerLossy250 | ||
618 | | MessengerLossy251 | ||
619 | | MessengerLossy252 | ||
620 | | MessengerLossy253 | ||
621 | | MessengerLossy254 | ||
622 | | Messenger255 -- ^ 255 reserved for Messenger usage (lossless packet) | ||
623 | deriving (Show,Eq,Enum,Ord,Bounded) | ||
624 | |||
70 | 625 | ||
71 | 626 | ||
627 | data MessageName = Ping -- 0x00 | ||
628 | | MessageName0x01 | ||
629 | | MessageName0x02 | ||
630 | | MessageName0x03 | ||
631 | | MessageName0x04 | ||
632 | | MessageName0x05 | ||
633 | | MessageName0x06 | ||
634 | | MessageName0x07 | ||
635 | | MessageName0x08 | ||
636 | | MessageName0x09 | ||
637 | | MessageName0x0a | ||
638 | | MessageName0x0b | ||
639 | | MessageName0x0c | ||
640 | | MessageName0x0d | ||
641 | | MessageName0x0e | ||
642 | | MessageName0x0f | ||
643 | | NewPeer -- 0x10 | ||
644 | | KillPeer -- 0x11 | ||
645 | | MessageName0x12 | ||
646 | | MessageName0x13 | ||
647 | | MessageName0x14 | ||
648 | | MessageName0x15 | ||
649 | | MessageName0x16 | ||
650 | | MessageName0x17 | ||
651 | | MessageName0x18 | ||
652 | | MessageName0x19 | ||
653 | | MessageName0x1a | ||
654 | | MessageName0x1b | ||
655 | | MessageName0x1c | ||
656 | | MessageName0x1d | ||
657 | | MessageName0x1e | ||
658 | | MessageName0x1f | ||
659 | | MessageName0x20 | ||
660 | | MessageName0x21 | ||
661 | | MessageName0x22 | ||
662 | | MessageName0x23 | ||
663 | | MessageName0x24 | ||
664 | | MessageName0x25 | ||
665 | | MessageName0x26 | ||
666 | | MessageName0x27 | ||
667 | | MessageName0x28 | ||
668 | | MessageName0x29 | ||
669 | | MessageName0x2a | ||
670 | | MessageName0x2b | ||
671 | | MessageName0x2c | ||
672 | | MessageName0x2d | ||
673 | | MessageName0x2e | ||
674 | | MessageName0x2f | ||
675 | | NameChange -- 0x30 | ||
676 | | GroupchatTitleChange -- 0x31 | ||
677 | | MessageName0x32 | ||
678 | | MessageName0x33 | ||
679 | | MessageName0x34 | ||
680 | | MessageName0x35 | ||
681 | | MessageName0x36 | ||
682 | | MessageName0x37 | ||
683 | | MessageName0x38 | ||
684 | | MessageName0x39 | ||
685 | | MessageName0x3a | ||
686 | | MessageName0x3b | ||
687 | | MessageName0x3c | ||
688 | | MessageName0x3d | ||
689 | | MessageName0x3e | ||
690 | | MessageName0x3f | ||
691 | | ChatMessage -- 0x40 | ||
692 | | Action -- 0x41 | ||
693 | | MessageName0x42 | ||
694 | | MessageName0x43 | ||
695 | | MessageName0x44 | ||
696 | | MessageName0x45 | ||
697 | | MessageName0x46 | ||
698 | | MessageName0x47 | ||
699 | | MessageName0x48 | ||
700 | | MessageName0x49 | ||
701 | | MessageName0x4a | ||
702 | | MessageName0x4b | ||
703 | | MessageName0x4c | ||
704 | | MessageName0x4d | ||
705 | | MessageName0x4e | ||
706 | | MessageName0x4f | ||
707 | | MessageName0x50 | ||
708 | | MessageName0x51 | ||
709 | | MessageName0x52 | ||
710 | | MessageName0x53 | ||
711 | | MessageName0x54 | ||
712 | | MessageName0x55 | ||
713 | | MessageName0x56 | ||
714 | | MessageName0x57 | ||
715 | | MessageName0x58 | ||
716 | | MessageName0x59 | ||
717 | | MessageName0x5a | ||
718 | | MessageName0x5b | ||
719 | | MessageName0x5c | ||
720 | | MessageName0x5d | ||
721 | | MessageName0x5e | ||
722 | | MessageName0x5f | ||
723 | | MessageName0x60 | ||
724 | | MessageName0x61 | ||
725 | | MessageName0x62 | ||
726 | | MessageName0x63 | ||
727 | | MessageName0x64 | ||
728 | | MessageName0x65 | ||
729 | | MessageName0x66 | ||
730 | | MessageName0x67 | ||
731 | | MessageName0x68 | ||
732 | | MessageName0x69 | ||
733 | | MessageName0x6a | ||
734 | | MessageName0x6b | ||
735 | | MessageName0x6c | ||
736 | | MessageName0x6d | ||
737 | | MessageName0x6e | ||
738 | | MessageName0x6f | ||
739 | | MessageName0x70 | ||
740 | | MessageName0x71 | ||
741 | | MessageName0x72 | ||
742 | | MessageName0x73 | ||
743 | | MessageName0x74 | ||
744 | | MessageName0x75 | ||
745 | | MessageName0x76 | ||
746 | | MessageName0x77 | ||
747 | | MessageName0x78 | ||
748 | | MessageName0x79 | ||
749 | | MessageName0x7a | ||
750 | | MessageName0x7b | ||
751 | | MessageName0x7c | ||
752 | | MessageName0x7d | ||
753 | | MessageName0x7e | ||
754 | | MessageName0x7f | ||
755 | | MessageName0x80 | ||
756 | | MessageName0x81 | ||
757 | | MessageName0x82 | ||
758 | | MessageName0x83 | ||
759 | | MessageName0x84 | ||
760 | | MessageName0x85 | ||
761 | | MessageName0x86 | ||
762 | | MessageName0x87 | ||
763 | | MessageName0x88 | ||
764 | | MessageName0x89 | ||
765 | | MessageName0x8a | ||
766 | | MessageName0x8b | ||
767 | | MessageName0x8c | ||
768 | | MessageName0x8d | ||
769 | | MessageName0x8e | ||
770 | | MessageName0x8f | ||
771 | | MessageName0x90 | ||
772 | | MessageName0x91 | ||
773 | | MessageName0x92 | ||
774 | | MessageName0x93 | ||
775 | | MessageName0x94 | ||
776 | | MessageName0x95 | ||
777 | | MessageName0x96 | ||
778 | | MessageName0x97 | ||
779 | | MessageName0x98 | ||
780 | | MessageName0x99 | ||
781 | | MessageName0x9a | ||
782 | | MessageName0x9b | ||
783 | | MessageName0x9c | ||
784 | | MessageName0x9d | ||
785 | | MessageName0x9e | ||
786 | | MessageName0x9f | ||
787 | | MessageName0xa0 | ||
788 | | MessageName0xa1 | ||
789 | | MessageName0xa2 | ||
790 | | MessageName0xa3 | ||
791 | | MessageName0xa4 | ||
792 | | MessageName0xa5 | ||
793 | | MessageName0xa6 | ||
794 | | MessageName0xa7 | ||
795 | | MessageName0xa8 | ||
796 | | MessageName0xa9 | ||
797 | | MessageName0xaa | ||
798 | | MessageName0xab | ||
799 | | MessageName0xac | ||
800 | | MessageName0xad | ||
801 | | MessageName0xae | ||
802 | | MessageName0xaf | ||
803 | | MessageName0xb0 | ||
804 | | MessageName0xb1 | ||
805 | | MessageName0xb2 | ||
806 | | MessageName0xb3 | ||
807 | | MessageName0xb4 | ||
808 | | MessageName0xb5 | ||
809 | | MessageName0xb6 | ||
810 | | MessageName0xb7 | ||
811 | | MessageName0xb8 | ||
812 | | MessageName0xb9 | ||
813 | | MessageName0xba | ||
814 | | MessageName0xbb | ||
815 | | MessageName0xbc | ||
816 | | MessageName0xbd | ||
817 | | MessageName0xbe | ||
818 | | MessageName0xbf | ||
819 | | MessageName0xc0 | ||
820 | | MessageName0xc1 | ||
821 | | MessageName0xc2 | ||
822 | | MessageName0xc3 | ||
823 | | MessageName0xc4 | ||
824 | | MessageName0xc5 | ||
825 | | MessageName0xc6 | ||
826 | | MessageName0xc7 | ||
827 | | MessageName0xc8 | ||
828 | | MessageName0xc9 | ||
829 | | MessageName0xca | ||
830 | | MessageName0xcb | ||
831 | | MessageName0xcc | ||
832 | | MessageName0xcd | ||
833 | | MessageName0xce | ||
834 | | MessageName0xcf | ||
835 | | MessageName0xd0 | ||
836 | | MessageName0xd1 | ||
837 | | MessageName0xd2 | ||
838 | | MessageName0xd3 | ||
839 | | MessageName0xd4 | ||
840 | | MessageName0xd5 | ||
841 | | MessageName0xd6 | ||
842 | | MessageName0xd7 | ||
843 | | MessageName0xd8 | ||
844 | | MessageName0xd9 | ||
845 | | MessageName0xda | ||
846 | | MessageName0xdb | ||
847 | | MessageName0xdc | ||
848 | | MessageName0xdd | ||
849 | | MessageName0xde | ||
850 | | MessageName0xdf | ||
851 | | MessageName0xe0 | ||
852 | | MessageName0xe1 | ||
853 | | MessageName0xe2 | ||
854 | | MessageName0xe3 | ||
855 | | MessageName0xe4 | ||
856 | | MessageName0xe5 | ||
857 | | MessageName0xe6 | ||
858 | | MessageName0xe7 | ||
859 | | MessageName0xe8 | ||
860 | | MessageName0xe9 | ||
861 | | MessageName0xea | ||
862 | | MessageName0xeb | ||
863 | | MessageName0xec | ||
864 | | MessageName0xed | ||
865 | | MessageName0xee | ||
866 | | MessageName0xef | ||
867 | | MessageName0xf0 | ||
868 | | MessageName0xf1 | ||
869 | | MessageName0xf2 | ||
870 | | MessageName0xf3 | ||
871 | | MessageName0xf4 | ||
872 | | MessageName0xf5 | ||
873 | | MessageName0xf6 | ||
874 | | MessageName0xf7 | ||
875 | | MessageName0xf8 | ||
876 | | MessageName0xf9 | ||
877 | | MessageName0xfa | ||
878 | | MessageName0xfb | ||
879 | | MessageName0xfc | ||
880 | | MessageName0xfd | ||
881 | | MessageName0xfe | ||
882 | | MessageName0xff | ||
883 | deriving (Show,Eq,Ord,Enum,Bounded) | ||
72 | 884 | ||
73 | -- --> CookieRequest WithoutCookie | 885 | -- --> CookieRequest WithoutCookie |
74 | -- <-- CookieResponse CookieAddress | 886 | -- <-- CookieResponse CookieAddress |