1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef _rostermodule_h_
29 #define _rostermodule_h_
30 
31 #include "talk/xmpp/module.h"
32 
33 namespace buzz {
34 
35 class XmppRosterModule;
36 
37 // The main way you initialize and use the module would be like this:
38 //    XmppRosterModule *roster_module = XmppRosterModule::Create();
39 //    roster_module->RegisterEngine(engine);
40 //    roster_module->BroadcastPresence();
41 //    roster_module->RequestRosterUpdate();
42 
43 //! This enum captures the valid values for the show attribute in a presence
44 //! stanza
45 enum XmppPresenceShow
46 {
47   XMPP_PRESENCE_CHAT = 0,
48   XMPP_PRESENCE_DEFAULT = 1,
49   XMPP_PRESENCE_AWAY = 2,
50   XMPP_PRESENCE_XA = 3,
51   XMPP_PRESENCE_DND = 4,
52 };
53 
54 //! These are the valid subscription states in a roster contact.  This
55 //! represents the combination of the subscription and ask attributes
56 enum XmppSubscriptionState
57 {
58   XMPP_SUBSCRIPTION_NONE = 0,
59   XMPP_SUBSCRIPTION_NONE_ASKED = 1,
60   XMPP_SUBSCRIPTION_TO = 2,
61   XMPP_SUBSCRIPTION_FROM = 3,
62   XMPP_SUBSCRIPTION_FROM_ASKED = 4,
63   XMPP_SUBSCRIPTION_BOTH = 5,
64 };
65 
66 //! These represent the valid types of presence stanzas for managing
67 //! subscriptions
68 enum XmppSubscriptionRequestType
69 {
70   XMPP_REQUEST_SUBSCRIBE = 0,
71   XMPP_REQUEST_UNSUBSCRIBE = 1,
72   XMPP_REQUEST_SUBSCRIBED = 2,
73   XMPP_REQUEST_UNSUBSCRIBED = 3,
74 };
75 
76 enum XmppPresenceAvailable {
77   XMPP_PRESENCE_UNAVAILABLE = 0,
78   XMPP_PRESENCE_AVAILABLE   = 1,
79   XMPP_PRESENCE_ERROR       = 2,
80 };
81 
82 //! Presence Information
83 //! This class stores both presence information for outgoing presence and is
84 //! returned by methods in XmppRosterModule to represent recieved incoming
85 //! presence information.  When this class is writeable (non-const) then each
86 //! update to any property will set the inner xml.  Setting the raw_xml will
87 //! rederive all of the other properties.
88 class XmppPresence {
89 public:
~XmppPresence()90   virtual ~XmppPresence() {}
91 
92   //! Create a new Presence
93   //! This is typically only used when sending a directed presence
94   static XmppPresence* Create();
95 
96   //! The Jid of for the presence information.
97   //! Typically this will be a full Jid with resource specified.
98   virtual const Jid jid() const = 0;
99 
100   //! Is the contact available?
101   virtual XmppPresenceAvailable available() const = 0;
102 
103   //! Sets if the user is available or not
104   virtual XmppReturnStatus set_available(XmppPresenceAvailable available) = 0;
105 
106   //! The show value of the presence info
107   virtual XmppPresenceShow presence_show() const = 0;
108 
109   //! Set the presence show value
110   virtual XmppReturnStatus set_presence_show(XmppPresenceShow show) = 0;
111 
112   //! The Priority of the presence info
113   virtual int priority() const = 0;
114 
115   //! Set the priority of the presence
116   virtual XmppReturnStatus set_priority(int priority) = 0;
117 
118   //! The plain text status of the presence info.
119   //! If there are multiple status because of language, this will either be a
120   //! status that is not tagged for language or the first available
121   virtual const std::string& status() const = 0;
122 
123   //! Sets the status for the presence info.
124   //! If there is more than one status present already then this will remove
125   //! them all and replace it with one status element we no specified language
126   virtual XmppReturnStatus set_status(const std::string& status) = 0;
127 
128   //! The raw xml of the presence update
129   virtual const XmlElement* raw_xml() const = 0;
130 
131   //! Sets the raw presence stanza for the presence update
132   //! This will cause all other data items in this structure to be rederived
133   virtual XmppReturnStatus set_raw_xml(const XmlElement * xml) = 0;
134 };
135 
136 //! A contact as given by the server
137 class XmppRosterContact {
138 public:
~XmppRosterContact()139   virtual ~XmppRosterContact() {}
140 
141   //! Create a new roster contact
142   //! This is typically only used when doing a roster update/add
143   static XmppRosterContact* Create();
144 
145   //! The jid for the contact.
146   //! Typically this will be a bare Jid.
147   virtual const Jid jid() const = 0;
148 
149   //! Sets the jid for the roster contact update
150   virtual XmppReturnStatus set_jid(const Jid& jid) = 0;
151 
152   //! The name (nickname) stored for this contact
153   virtual const std::string& name() const = 0;
154 
155   //! Sets the name
156   virtual XmppReturnStatus set_name(const std::string& name) = 0;
157 
158   //! The Presence subscription state stored on the server for this contact
159   //! This is never settable and will be ignored when generating a roster
160   //! add/update request
161   virtual XmppSubscriptionState subscription_state() const = 0;
162 
163   //! The number of Groups applied to this contact
164   virtual size_t GetGroupCount() const = 0;
165 
166   //! Gets a Group applied to the contact based on index.
167   //! range
168   virtual const std::string& GetGroup(size_t index) const = 0;
169 
170   //! Adds a group to this contact.
171   //! This will return a bad argument error if the group is already there.
172   virtual XmppReturnStatus AddGroup(const std::string& group) = 0;
173 
174   //! Removes a group from the contact.
175   //! This will return an error if the group cannot be found in the group list.
176   virtual XmppReturnStatus RemoveGroup(const std::string& group) = 0;
177 
178   //! The raw xml for this roster contact
179   virtual const XmlElement* raw_xml() const = 0;
180 
181   //! Sets the raw presence stanza for the contact update/add
182   //! This will cause all other data items in this structure to be rederived
183   virtual XmppReturnStatus set_raw_xml(const XmlElement * xml) = 0;
184 };
185 
186 //! The XmppRosterHandler is an interface for callbacks from the module
187 class XmppRosterHandler {
188 public:
~XmppRosterHandler()189   virtual ~XmppRosterHandler() {}
190 
191   //! A request for a subscription has come in.
192   //! Typically, the UI will ask the user if it is okay to let the requester
193   //! get presence notifications for the user.  The response is send back
194   //! by calling ApproveSubscriber or CancelSubscriber.
195   virtual void SubscriptionRequest(XmppRosterModule* roster,
196                                    const Jid& requesting_jid,
197                                    XmppSubscriptionRequestType type,
198                                    const XmlElement* raw_xml) = 0;
199 
200   //! Some type of presence error has occurred
201   virtual void SubscriptionError(XmppRosterModule* roster,
202                                  const Jid& from,
203                                  const XmlElement* raw_xml) = 0;
204 
205   virtual void RosterError(XmppRosterModule* roster,
206                            const XmlElement* raw_xml) = 0;
207 
208   //! New presence information has come in
209   //! The user is notified with the presence object directly.  This info is also
210   //! added to the store accessable from the engine.
211   virtual void IncomingPresenceChanged(XmppRosterModule* roster,
212                                        const XmppPresence* presence) = 0;
213 
214   //! A contact has changed
215   //! This indicates that the data for a contact may have changed.  No
216   //! contacts have been added or removed.
217   virtual void ContactChanged(XmppRosterModule* roster,
218                               const XmppRosterContact* old_contact,
219                               size_t index) = 0;
220 
221   //! A set of contacts have been added
222   //! These contacts may have been added in response to the original roster
223   //! request or due to a "roster push" from the server.
224   virtual void ContactsAdded(XmppRosterModule* roster,
225                              size_t index, size_t number) = 0;
226 
227   //! A contact has been removed
228   //! This contact has been removed form the list.
229   virtual void ContactRemoved(XmppRosterModule* roster,
230                               const XmppRosterContact* removed_contact,
231                               size_t index) = 0;
232 
233 };
234 
235 //! An XmppModule for handle roster and presence functionality
236 class XmppRosterModule : public XmppModule {
237 public:
238   //! Creates a new XmppRosterModule
239   static XmppRosterModule * Create();
~XmppRosterModule()240   virtual ~XmppRosterModule() {}
241 
242   //! Sets the roster handler (callbacks) for the module
243   virtual XmppReturnStatus set_roster_handler(XmppRosterHandler * handler) = 0;
244 
245   //! Gets the roster handler for the module
246   virtual XmppRosterHandler* roster_handler() = 0;
247 
248   // USER PRESENCE STATE -------------------------------------------------------
249 
250   //! Gets the aggregate outgoing presence
251   //! This object is non-const and be edited directly.  No update is sent
252   //! to the server until a Broadcast is sent
253   virtual XmppPresence* outgoing_presence() = 0;
254 
255   //! Broadcasts that the user is available.
256   //! Nothing with respect to presence is sent until this is called.
257   virtual XmppReturnStatus BroadcastPresence() = 0;
258 
259   //! Sends a directed presence to a Jid
260   //! Note that the client doesn't store where directed presence notifications
261   //! have been sent.  The server can keep the appropriate state
262   virtual XmppReturnStatus SendDirectedPresence(const XmppPresence* presence,
263                                                 const Jid& to_jid) = 0;
264 
265   // INCOMING PRESENCE STATUS --------------------------------------------------
266 
267   //! Returns the number of incoming presence data recorded
268   virtual size_t GetIncomingPresenceCount() = 0;
269 
270   //! Returns an incoming presence datum based on index
271   virtual const XmppPresence* GetIncomingPresence(size_t index) = 0;
272 
273   //! Gets the number of presence data for a bare Jid
274   //! There may be a datum per resource
275   virtual size_t GetIncomingPresenceForJidCount(const Jid& jid) = 0;
276 
277   //! Returns a single presence data for a Jid based on index
278   virtual const XmppPresence* GetIncomingPresenceForJid(const Jid& jid,
279                                                         size_t index) = 0;
280 
281   // ROSTER MANAGEMENT ---------------------------------------------------------
282 
283   //! Requests an update of the roster from the server
284   //! This must be called to initialize the client side cache of the roster
285   //! After this is sent the server should keep this module apprised of any
286   //! changes.
287   virtual XmppReturnStatus RequestRosterUpdate() = 0;
288 
289   //! Returns the number of contacts in the roster
290   virtual size_t GetRosterContactCount() = 0;
291 
292   //! Returns a contact by index
293   virtual const XmppRosterContact* GetRosterContact(size_t index) = 0;
294 
295   //! Finds a contact by Jid
296   virtual const XmppRosterContact* FindRosterContact(const Jid& jid) = 0;
297 
298   //! Send a request to the server to add a contact
299   //! Note that the contact won't show up in the roster until the server can
300   //! respond.  This happens async when the socket is being serviced
301   virtual XmppReturnStatus RequestRosterChange(
302     const XmppRosterContact* contact) = 0;
303 
304   //! Request that the server remove a contact
305   //! The jabber protocol specifies that the server should also cancel any
306   //! subscriptions when this is done.  Like adding, this contact won't be
307   //! removed until the server responds.
308   virtual XmppReturnStatus RequestRosterRemove(const Jid& jid) = 0;
309 
310   // SUBSCRIPTION MANAGEMENT ---------------------------------------------------
311 
312   //! Request a subscription to presence notifications form a Jid
313   virtual XmppReturnStatus RequestSubscription(const Jid& jid) = 0;
314 
315   //! Cancel a subscription to presence notifications from a Jid
316   virtual XmppReturnStatus CancelSubscription(const Jid& jid) = 0;
317 
318   //! Approve a request to deliver presence notifications to a jid
319   virtual XmppReturnStatus ApproveSubscriber(const Jid& jid) = 0;
320 
321   //! Deny or cancel presence notification deliver to a jid
322   virtual XmppReturnStatus CancelSubscriber(const Jid& jid) = 0;
323 };
324 
325 }
326 
327 #endif
328