More implementation of XMPP, thanks a lot to Federico Pinna & Reitek S.p.A.
[pwlib.git] / include / ptclib / xmpp.h
blob9ba17ab36fcbce0e0b934aeaa6b6c04a56df4d00
1 /*
2 * xmpp.h
4 * Extensible Messaging and Presence Protocol (XMPP) Core
6 * Portable Windows Library
8 * Copyright (c) 2004 Reitek S.p.A.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Post Increment
24 * Contributor(s): ______________________________________.
26 * $Log$
27 * Revision 1.2 2004/04/26 01:51:57 rjongbloed
28 * More implementation of XMPP, thanks a lot to Federico Pinna & Reitek S.p.A.
30 * Revision 1.1 2004/04/22 12:31:00 rjongbloed
31 * Added PNotifier extensions and XMPP (Jabber) support,
32 * thanks to Federico Pinna and Reitek S.p.A.
37 #ifndef _XMPP
38 #define _XMPP
40 #ifdef P_USE_PRAGMA
41 #pragma interface
42 #endif
44 #include <ptbuildopts.h>
46 #if P_EXPAT
48 #include <ptclib/pxml.h>
49 #include <ptlib/notifier_ext.h>
52 ///////////////////////////////////////////////////////
54 namespace XMPP
56 /** Various constant strings
58 extern const PString Language;
59 extern const PString Namespace;
60 extern const PString MessageStanza;
61 extern const PString PresenceStanza;
62 extern const PString IQStanza;
63 extern const PString IQQuery;
65 class JID : public PObject
67 PCLASSINFO(JID, PObject);
69 public:
70 JID(const char * jid = 0);
71 JID(const PString& jid);
72 JID(const PString& user, const PString& server, const PString& resource = PString::Empty());
74 virtual Comparison Compare(
75 const PObject & obj // Object to compare against.
76 ) const;
78 PString & operator=(
79 const PString & jid /// New JID to assign.
82 operator const PString&() const;
84 PString GetUser() const { return m_User; }
85 PString GetServer() const { return m_Server; }
86 PString GetResource() const { return m_Resource; }
87 PString GetShortFormat() const { return m_User + "@" + m_Server; }
89 void SetUser(const PString& user);
90 void SetServer(const PString& server);
91 void SetResource(const PString& resource);
93 protected:
94 void ParseJID(const PString& jid);
95 void BuildJID() const;
97 PString m_User;
98 PString m_Server;
99 PString m_Resource;
101 mutable PString m_JID;
102 mutable BOOL m_IsDirty;
105 /** This interface is the base class of each XMPP transport class
107 Derived classes might include an XMPP TCP transport as well as
108 classes to handle XMPP incapsulated in SIP messages.
110 class Transport : public PIndirectChannel
112 PCLASSINFO(Transport, PIndirectChannel);
114 public:
115 virtual BOOL Open() = 0;
116 virtual BOOL Close() = 0;
120 /** This class represents a XMPP stream, i.e. a XML message exchange
121 between XMPP entities
123 class Stream : public PIndirectChannel
125 PCLASSINFO(Stream, PIndirectChannel);
127 public:
128 Stream(Transport * transport = 0);
129 ~Stream();
131 virtual BOOL OnOpen() { return m_OpenHandlers.Fire(*this); }
132 PNotifierList& OpenHandlers() { return m_OpenHandlers; }
134 virtual BOOL Close();
135 virtual void OnClose() { m_CloseHandlers.Fire(*this); }
136 PNotifierList& CloseHandlers() { return m_CloseHandlers; }
138 virtual BOOL Write(const void * buf, PINDEX len);
139 virtual BOOL Write(const PString& data);
140 virtual BOOL Write(const PXML& pdu);
142 /** Read a XMPP stanza from the stream
144 virtual PXML * Read();
146 /** Reset the parser. The will delete and re-instantiate the
147 XML stream parser.
149 virtual void Reset();
150 PXMLStreamParser * GetParser() { return m_Parser; }
152 protected:
153 PXMLStreamParser * m_Parser;
154 PNotifierList m_OpenHandlers;
155 PNotifierList m_CloseHandlers;
159 class BaseStreamHandler : public PThread
161 PCLASSINFO(BaseStreamHandler, PThread);
163 public:
164 BaseStreamHandler();
165 ~BaseStreamHandler();
167 virtual BOOL Start(Transport * transport = 0);
168 virtual BOOL Stop(const PString& error = PString::Empty());
170 void SetAutoReconnect(BOOL b = TRUE, long timeout = 1000);
172 PNotifierList& ElementHandlers() { return m_ElementHandlers; }
173 Stream * GetStream() { return m_Stream; }
175 virtual BOOL Write(const void * buf, PINDEX len);
176 virtual BOOL Write(const PString& data);
177 virtual BOOL Write(const PXML& pdu);
178 virtual void OnElement(PXML& pdu);
180 virtual void Main();
182 protected:
183 PDECLARE_NOTIFIER(Stream, BaseStreamHandler, OnOpen);
184 PDECLARE_NOTIFIER(Stream, BaseStreamHandler, OnClose);
186 Stream * m_Stream;
187 BOOL m_AutoReconnect;
188 PTimeInterval m_ReconnectTimeout;
190 PNotifierList m_ElementHandlers;
194 /** XMPP stanzas: the following classes represent the three
195 stanzas (PDUs) defined by the xmpp protocol
198 class Stanza : public PXML
200 PCLASSINFO(Stanza, PXML)
202 public:
203 /** Various constant strings
205 static const PString ID;
206 static const PString From;
207 static const PString To;
209 virtual BOOL IsValid() const = 0;
211 virtual PString GetID() const;
212 virtual PString GetFrom() const;
213 virtual PString GetTo() const;
215 virtual void SetID(const PString& id);
216 virtual void SetFrom(const PString& from);
217 virtual void SetTo(const PString& to);
220 PLIST(StanzaList, Stanza);
223 class Message : public Stanza
225 PCLASSINFO(Message, Stanza)
227 public:
228 enum MessageType {
229 Normal,
230 Chat,
231 Error,
232 GroupChat,
233 HeadLine,
234 Unknown = 999
237 /** Various constant strings
239 static const PString Type;
240 static const PString Subject;
241 static const PString Body;
242 static const PString Thread;
244 /** Construct a new empty message
246 Message();
248 /** Construct a message from a (received) xml PDU.
249 The root of the pdu MUST be a message stanza.
250 NOTE: the root of the pdu is cloned.
252 Message(PXML& pdu);
253 Message(PXML * pdu);
255 virtual BOOL IsValid() const;
256 static BOOL IsValid(const PXML * pdu);
258 virtual MessageType GetType(PString * typeName = 0) const;
259 virtual PString GetLanguage() const;
261 /** Get the subject for the specified language. The default subject (if any)
262 is returned in case no language is specified or a matching one cannot be
263 found
265 virtual PString GetSubject(const PString& lang = PString::Empty());
266 virtual PString GetBody(const PString& lang = PString::Empty());
267 virtual PString GetThread();
269 virtual PXMLElement * GetSubjectElement(const PString& lang = PString::Empty());
270 virtual PXMLElement * GetBodyElement(const PString& lang = PString::Empty());
272 virtual void SetType(MessageType type);
273 virtual void SetType(const PString& type); // custom, possibly non standard, type
274 virtual void SetLanguage(const PString& lang);
276 virtual void SetSubject(const PString& subj, const PString& lang = PString::Empty());
277 virtual void SetBody(const PString& body, const PString& lang = PString::Empty());
278 virtual void SetThread(const PString& thrd);
282 class Presence : public Stanza
284 PCLASSINFO(Presence, Stanza)
286 public:
287 enum PresenceType {
288 Available,
289 Unavailable,
290 Subscribe,
291 Subscribed,
292 Unsubscribe,
293 Unsubscribed,
294 Probe,
295 Error,
296 Unknown = 999
299 enum ShowType {
300 Online,
301 Away,
302 Chat,
303 DND,
305 Other = 999
308 /** Various constant strings
310 static const PString Type;
311 static const PString Show;
312 static const PString Status;
313 static const PString Priority;
315 /** Construct a new empty presence
317 Presence();
319 /** Construct a presence from a (received) xml PDU.
320 The root of the pdu MUST be a presence stanza.
321 NOTE: the root of the pdu is cloned.
323 Presence(PXML& pdu);
324 Presence(PXML * pdu);
326 virtual BOOL IsValid() const;
327 static BOOL IsValid(const PXML * pdu);
329 virtual PresenceType GetType(PString * typeName = 0) const;
330 virtual ShowType GetShow(PString * showName = 0) const;
331 virtual BYTE GetPriority() const;
333 /** Get the status for the specified language. The default status (if any)
334 is returned in case no language is specified or a matching one cannot be
335 found
337 virtual PString GetStatus(const PString& lang = PString::Empty());
338 virtual PXMLElement * GetStatusElement(const PString& lang = PString::Empty());
340 virtual void SetType(PresenceType type);
341 virtual void SetType(const PString& type); // custom, possibly non standard, type
342 virtual void SetShow(ShowType show);
343 virtual void SetShow(const PString& show); // custom, possibly non standard, type
344 virtual void SetPriority(BYTE priority);
346 virtual void SetStatus(const PString& status, const PString& lang = PString::Empty());
350 class IQ : public Stanza
352 PCLASSINFO(IQ, Stanza)
354 public:
355 enum IQType {
356 Get,
357 Set,
358 Result,
359 Error,
360 Unknown = 999
363 /** Various constant strings
365 static const PString Type;
367 IQ(IQType type, PXMLElement * body = 0);
368 IQ(PXML& pdu);
369 IQ(PXML * pdu);
370 ~IQ();
372 virtual BOOL IsValid() const;
373 static BOOL IsValid(const PXML * pdu);
375 /** This method signals that the message was taken care of
376 If the stream handler, after firing all the notifiers finds
377 that an iq set/get pdu has not being processed, it returns
378 an error to the sender
380 void SetProcessed() { m_Processed = TRUE; }
381 BOOL HasBeenProcessed() const { return m_Processed; }
383 virtual IQType GetType(PString * typeName = 0) const;
384 virtual PXMLElement * GetBody();
386 virtual void SetType(IQType type);
387 virtual void SetType(const PString& type); // custom, possibly non standard, type
388 virtual void SetBody(PXMLElement * body);
390 // If the this message is response, returns a pointer to the
391 // original set/get message
392 virtual IQ * GetOriginalMessage() const { return m_OriginalIQ; }
393 virtual void SetOriginalMessage(IQ * iq);
395 /** Creates a new response iq for this message (that must
396 be of the set/get type!)
398 virtual IQ * BuildResult() const;
400 /** Creates an error response for this message
402 virtual IQ * BuildError(const PString& type, const PString& code) const;
404 virtual PNotifierList GetResponseHandlers() { return m_ResponseHandlers; }
406 static PString GenerateID();
408 protected:
409 BOOL m_Processed;
410 IQ * m_OriginalIQ;
411 PNotifierList m_ResponseHandlers;
414 }; // class XMPP
417 #endif // P_EXPAT
419 #endif // _XMPP
421 // End of File ///////////////////////////////////////////////////////////////