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 _rostermoduleimpl_h_ 29 #define _rostermoduleimpl_h_ 30 31 #include "talk/xmpp/moduleimpl.h" 32 #include "talk/xmpp/rostermodule.h" 33 34 namespace buzz { 35 36 //! Presence Information 37 //! This class stores both presence information for outgoing presence and is 38 //! returned by methods in XmppRosterModule to represent received incoming 39 //! presence information. When this class is writeable (non-const) then each 40 //! update to any property will set the inner xml. Setting the raw_xml will 41 //! rederive all of the other properties. 42 class XmppPresenceImpl : public XmppPresence { 43 public: 44 virtual ~XmppPresenceImpl() {} 45 46 //! The from Jid of for the presence information. 47 //! Typically this will be a full Jid with resource specified. For outgoing 48 //! presence this should remain JID_NULL and will be scrubbed from the 49 //! stanza when being sent. 50 virtual const Jid jid() const; 51 52 //! Is the contact available? 53 virtual XmppPresenceAvailable available() const; 54 55 //! Sets if the user is available or not 56 virtual XmppReturnStatus set_available(XmppPresenceAvailable available); 57 58 //! The show value of the presence info 59 virtual XmppPresenceShow presence_show() const; 60 61 //! Set the presence show value 62 virtual XmppReturnStatus set_presence_show(XmppPresenceShow show); 63 64 //! The Priority of the presence info 65 virtual int priority() const; 66 67 //! Set the priority of the presence 68 virtual XmppReturnStatus set_priority(int priority); 69 70 //! The plain text status of the presence info. 71 //! If there are multiple status because of language, this will either be a 72 //! status that is not tagged for language or the first available 73 virtual const std::string status() const; 74 75 //! Sets the status for the presence info. 76 //! If there is more than one status present already then this will remove 77 //! them all and replace it with one status element we no specified language 78 virtual XmppReturnStatus set_status(const std::string& status); 79 80 //! The connection status 81 virtual XmppPresenceConnectionStatus connection_status() const; 82 83 //! The focus obfuscated GAIA id 84 virtual const std::string google_user_id() const; 85 86 //! The nickname in the presence 87 virtual const std::string nickname() const; 88 89 //! The raw xml of the presence update 90 virtual const XmlElement* raw_xml() const; 91 92 //! Sets the raw presence stanza for the presence update 93 //! This will cause all other data items in this structure to be rederived 94 virtual XmppReturnStatus set_raw_xml(const XmlElement * xml); 95 96 private: 97 XmppPresenceImpl(); 98 99 friend class XmppPresence; 100 friend class XmppRosterModuleImpl; 101 102 void CreateRawXmlSkeleton(); 103 104 // Store everything in the XML element. If this becomes a perf issue we can 105 // cache the data. 106 talk_base::scoped_ptr<XmlElement> raw_xml_; 107 }; 108 109 //! A contact as given by the server 110 class XmppRosterContactImpl : public XmppRosterContact { 111 public: 112 virtual ~XmppRosterContactImpl() {} 113 114 //! The jid for the contact. 115 //! Typically this will be a bare Jid. 116 virtual const Jid jid() const; 117 118 //! Sets the jid for the roster contact update 119 virtual XmppReturnStatus set_jid(const Jid& jid); 120 121 //! The name (nickname) stored for this contact 122 virtual const std::string name() const; 123 124 //! Sets the name 125 virtual XmppReturnStatus set_name(const std::string& name); 126 127 //! The Presence subscription state stored on the server for this contact 128 //! This is never settable and will be ignored when generating a roster 129 //! add/update request 130 virtual XmppSubscriptionState subscription_state() const; 131 132 //! The number of Groups applied to this contact 133 virtual size_t GetGroupCount() const; 134 135 //! Gets a Group applied to the contact based on index. 136 virtual const std::string GetGroup(size_t index) const; 137 138 //! Adds a group to this contact. 139 //! This will return a no error if the group is already present. 140 virtual XmppReturnStatus AddGroup(const std::string& group); 141 142 //! Removes a group from the contact. 143 //! This will return no error if the group isn't there 144 virtual XmppReturnStatus RemoveGroup(const std::string& group); 145 146 //! The raw xml for this roster contact 147 virtual const XmlElement* raw_xml() const; 148 149 //! Sets the raw presence stanza for the presence update 150 //! This will cause all other data items in this structure to be rederived 151 virtual XmppReturnStatus set_raw_xml(const XmlElement * xml); 152 153 private: 154 XmppRosterContactImpl(); 155 156 void CreateRawXmlSkeleton(); 157 void SetXmlFromWire(const XmlElement * xml); 158 void ResetGroupCache(); 159 160 bool FindGroup(const std::string& group, 161 XmlElement** element, 162 XmlChild** child_before); 163 164 165 friend class XmppRosterContact; 166 friend class XmppRosterModuleImpl; 167 168 int group_count_; 169 int group_index_returned_; 170 XmlElement * group_returned_; 171 talk_base::scoped_ptr<XmlElement> raw_xml_; 172 }; 173 174 //! An XmppModule for handle roster and presence functionality 175 class XmppRosterModuleImpl : public XmppModuleImpl, 176 public XmppRosterModule, public XmppIqHandler { 177 public: 178 virtual ~XmppRosterModuleImpl(); 179 180 IMPLEMENT_XMPPMODULE 181 182 //! Sets the roster handler (callbacks) for the module 183 virtual XmppReturnStatus set_roster_handler(XmppRosterHandler * handler); 184 185 //! Gets the roster handler for the module 186 virtual XmppRosterHandler* roster_handler(); 187 188 // USER PRESENCE STATE ------------------------------------------------------- 189 190 //! Gets the aggregate outgoing presence 191 //! This object is non-const and be edited directly. No update is sent 192 //! to the server until a Broadcast is sent 193 virtual XmppPresence* outgoing_presence(); 194 195 //! Broadcasts that the user is available. 196 //! Nothing with respect to presence is sent until this is called. 197 virtual XmppReturnStatus BroadcastPresence(); 198 199 //! Sends a directed presence to a Jid 200 //! Note that the client doesn't store where directed presence notifications 201 //! have been sent. The server can keep the appropriate state 202 virtual XmppReturnStatus SendDirectedPresence(const XmppPresence* presence, 203 const Jid& to_jid); 204 205 // INCOMING PRESENCE STATUS -------------------------------------------------- 206 207 //! Returns the number of incoming presence data recorded 208 virtual size_t GetIncomingPresenceCount(); 209 210 //! Returns an incoming presence datum based on index 211 virtual const XmppPresence* GetIncomingPresence(size_t index); 212 213 //! Gets the number of presence data for a bare Jid 214 //! There may be a datum per resource 215 virtual size_t GetIncomingPresenceForJidCount(const Jid& jid); 216 217 //! Returns a single presence data for a Jid based on index 218 virtual const XmppPresence* GetIncomingPresenceForJid(const Jid& jid, 219 size_t index); 220 221 // ROSTER MANAGEMENT --------------------------------------------------------- 222 223 //! Requests an update of the roster from the server 224 //! This must be called to initialize the client side cache of the roster 225 //! After this is sent the server should keep this module apprised of any 226 //! changes. 227 virtual XmppReturnStatus RequestRosterUpdate(); 228 229 //! Returns the number of contacts in the roster 230 virtual size_t GetRosterContactCount(); 231 232 //! Returns a contact by index 233 virtual const XmppRosterContact* GetRosterContact(size_t index); 234 235 //! Finds a contact by Jid 236 virtual const XmppRosterContact* FindRosterContact(const Jid& jid); 237 238 //! Send a request to the server to add a contact 239 //! Note that the contact won't show up in the roster until the server can 240 //! respond. This happens async when the socket is being serviced 241 virtual XmppReturnStatus RequestRosterChange( 242 const XmppRosterContact* contact); 243 244 //! Request that the server remove a contact 245 //! The jabber protocol specifies that the server should also cancel any 246 //! subscriptions when this is done. Like adding, this contact won't be 247 //! removed until the server responds. 248 virtual XmppReturnStatus RequestRosterRemove(const Jid& jid); 249 250 // SUBSCRIPTION MANAGEMENT --------------------------------------------------- 251 252 //! Request a subscription to presence notifications form a Jid 253 virtual XmppReturnStatus RequestSubscription(const Jid& jid); 254 255 //! Cancel a subscription to presence notifications from a Jid 256 virtual XmppReturnStatus CancelSubscription(const Jid& jid); 257 258 //! Approve a request to deliver presence notifications to a jid 259 virtual XmppReturnStatus ApproveSubscriber(const Jid& jid); 260 261 //! Deny or cancel presence notification deliver to a jid 262 virtual XmppReturnStatus CancelSubscriber(const Jid& jid); 263 264 // XmppIqHandler IMPLEMENTATION ---------------------------------------------- 265 virtual void IqResponse(XmppIqCookie cookie, const XmlElement * stanza); 266 267 protected: 268 // XmppModuleImpl OVERRIDES -------------------------------------------------- 269 virtual bool HandleStanza(const XmlElement *); 270 271 // PRIVATE DATA -------------------------------------------------------------- 272 private: 273 friend class XmppRosterModule; 274 XmppRosterModuleImpl(); 275 276 // Helper functions 277 void DeleteIncomingPresence(); 278 void DeleteContacts(); 279 XmppReturnStatus SendSubscriptionRequest(const Jid& jid, 280 const std::string& type); 281 void InternalSubscriptionRequest(const Jid& jid, const XmlElement* stanza, 282 XmppSubscriptionRequestType request_type); 283 void InternalIncomingPresence(const Jid& jid, const XmlElement* stanza); 284 void InternalIncomingPresenceError(const Jid& jid, const XmlElement* stanza); 285 void InternalRosterItems(const XmlElement* stanza); 286 287 // Member data 288 XmppPresenceImpl outgoing_presence_; 289 XmppRosterHandler* roster_handler_; 290 291 typedef std::vector<XmppPresenceImpl*> PresenceVector; 292 typedef std::map<Jid, PresenceVector*> JidPresenceVectorMap; 293 talk_base::scoped_ptr<JidPresenceVectorMap> incoming_presence_map_; 294 talk_base::scoped_ptr<PresenceVector> incoming_presence_vector_; 295 296 typedef std::vector<XmppRosterContactImpl*> ContactVector; 297 talk_base::scoped_ptr<ContactVector> contacts_; 298 }; 299 300 } 301 302 #endif 303