summaryrefslogtreecommitdiff
path: root/Presence/Stanza/Types.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/Stanza/Types.hs')
-rw-r--r--Presence/Stanza/Types.hs184
1 files changed, 184 insertions, 0 deletions
diff --git a/Presence/Stanza/Types.hs b/Presence/Stanza/Types.hs
new file mode 100644
index 00000000..6b402f4d
--- /dev/null
+++ b/Presence/Stanza/Types.hs
@@ -0,0 +1,184 @@
1{-# LANGUAGE FlexibleInstances #-}
2module Stanza.Types where
3
4import Control.Concurrent.STM
5import Data.Int
6import Data.Text
7import Data.XML.Types as XML
8
9import Connection (PeerAddress(..))
10import ConnectionKey (ClientAddress(..))
11import LockedChan
12import Nesting (Lang)
13
14type Stanza = StanzaWrap (LockedChan XML.Event)
15
16data StanzaWrap a = Stanza
17 { stanzaType :: StanzaType
18 , stanzaId :: Maybe Text
19 , stanzaTo :: Maybe Text
20 , stanzaFrom :: Maybe Text
21 , stanzaChan :: a
22 , stanzaClosers :: TVar (Maybe [XML.Event])
23 , stanzaInterrupt :: TMVar ()
24 , stanzaOrigin :: StanzaOrigin
25 }
26
27data StanzaOrigin = LocalPeer
28 | PeerOrigin PeerAddress (TChan Stanza)
29 | ClientOrigin ClientAddress (TChan Stanza)
30
31data StanzaType
32 = Unrecognized
33 | Ping
34 | Pong
35 | RequestResource (Maybe Text) (Maybe Text) -- ^ Client's name for this host followed by client's requested resource id.
36 | SetResource
37 | SessionRequest
38 | UnrecognizedQuery Name
39 | RequestRoster
40 | Roster
41 | RosterEvent { rosterEventType :: RosterEventType
42 , rosterUser :: Text
43 , rosterContact :: Text }
44 | Error StanzaError XML.Event
45 | PresenceStatus { presenceShow :: JabberShow
46 , presencePriority :: Maybe Int8
47 , presenceStatus :: [(Lang,Text)]
48 , presenceWhiteList :: [Text]
49 }
50 | PresenceInformError
51 | PresenceInformSubscription Bool
52 | PresenceRequestStatus
53 | PresenceRequestSubscription Bool
54 | Message { msgThread :: Maybe MessageThread
55 , msgLangMap :: [(Lang,LangSpecificMessage)]
56 }
57 | NotifyClientVersion { versionName :: Text
58 , versionVersion :: Text }
59 | InternalEnableHack ClientHack
60 | InternalCacheId Text
61 deriving (Show,Eq)
62
63data RosterEventType
64 = RequestedSubscription
65 | NewBuddy -- preceded by PresenceInformSubscription True
66 | RemovedBuddy -- preceded by PresenceInformSubscription False
67 | PendingSubscriber -- same as PresenceRequestSubscription
68 | NewSubscriber
69 | RejectSubscriber
70 deriving (Show,Read,Ord,Eq,Enum)
71
72data ClientHack = SimulatedChatErrors
73 deriving (Show,Read,Ord,Eq,Enum)
74
75
76data LangSpecificMessage =
77 LangSpecificMessage { msgBody :: Maybe Text
78 , msgSubject :: Maybe Text
79 }
80 deriving (Show,Eq)
81
82data MessageThread = MessageThread {
83 msgThreadParent :: Maybe Text,
84 msgThreadContent :: Text
85 }
86 deriving (Show,Eq)
87
88
89data JabberShow = Offline
90 | ExtendedAway
91 | Away
92 | DoNotDisturb
93 | Available
94 | Chatty
95 deriving (Show,Enum,Ord,Eq,Read)
96
97class StanzaFirstTag a where
98 stanzaFirstTag :: StanzaWrap a -> IO XML.Event
99instance StanzaFirstTag (TChan XML.Event) where
100 stanzaFirstTag stanza = do
101 e <-atomically $ peekTChan (stanzaChan stanza)
102 return e
103instance StanzaFirstTag (LockedChan XML.Event) where
104 stanzaFirstTag stanza = do
105 e <-atomically $ peekLChan (stanzaChan stanza)
106 return e
107instance StanzaFirstTag XML.Event where
108 stanzaFirstTag stanza = return (stanzaChan stanza)
109
110data StanzaError
111 = BadRequest
112 | Conflict
113 | FeatureNotImplemented
114 | Forbidden
115 | Gone
116 | InternalServerError
117 | ItemNotFound
118 | JidMalformed
119 | NotAcceptable
120 | NotAllowed
121 | NotAuthorized
122 | PaymentRequired
123 | RecipientUnavailable
124 | Redirect
125 | RegistrationRequired
126 | RemoteServerNotFound
127 | RemoteServerTimeout
128 | ResourceConstraint
129 | ServiceUnavailable
130 | SubscriptionRequired
131 | UndefinedCondition
132 | UnexpectedRequest
133 deriving (Show,Enum,Ord,Eq)
134
135xep0086 :: StanzaError -> (Text, Int)
136xep0086 e = case e of
137 BadRequest -> ("modify", 400)
138 Conflict -> ("cancel", 409)
139 FeatureNotImplemented -> ("cancel", 501)
140 Forbidden -> ("auth", 403)
141 Gone -> ("modify", 302)
142 InternalServerError -> ("wait", 500)
143 ItemNotFound -> ("cancel", 404)
144 JidMalformed -> ("modify", 400)
145 NotAcceptable -> ("modify", 406)
146 NotAllowed -> ("cancel", 405)
147 NotAuthorized -> ("auth", 401)
148 PaymentRequired -> ("auth", 402)
149 RecipientUnavailable -> ("wait", 404)
150 Redirect -> ("modify", 302)
151 RegistrationRequired -> ("auth", 407)
152 RemoteServerNotFound -> ("cancel", 404)
153 RemoteServerTimeout -> ("wait", 504)
154 ResourceConstraint -> ("wait", 500)
155 ServiceUnavailable -> ("cancel", 503)
156 SubscriptionRequired -> ("auth", 407)
157 UndefinedCondition -> ("", 500)
158 UnexpectedRequest -> ("wait", 400)
159
160errorText :: StanzaError -> Text
161errorText e = case e of
162 BadRequest -> "Bad request"
163 Conflict -> "Conflict"
164 FeatureNotImplemented -> "This feature is not implemented"
165 Forbidden -> "Forbidden"
166 Gone -> "Recipient can no longer be contacted"
167 InternalServerError -> "Internal server error"
168 ItemNotFound -> "Item not found"
169 JidMalformed -> "JID Malformed"
170 NotAcceptable -> "Message was rejected"
171 NotAllowed -> "Not allowed"
172 NotAuthorized -> "Not authorized"
173 PaymentRequired -> "Payment is required"
174 RecipientUnavailable -> "Recipient is unavailable"
175 Redirect -> "Redirect"
176 RegistrationRequired -> "Registration required"
177 RemoteServerNotFound -> "Recipient's server not found"
178 RemoteServerTimeout -> "Remote server timeout"
179 ResourceConstraint -> "The server is low on resources"
180 ServiceUnavailable -> "The service is unavailable"
181 SubscriptionRequired -> "A subscription is required"
182 UndefinedCondition -> "Undefined condition"
183 UnexpectedRequest -> "Unexpected request"
184