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
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Post Increment
24 * Contributor(s): ______________________________________.
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.
44 #include <ptbuildopts.h>
48 #include <ptclib/pxml.h>
49 #include <ptlib/notifier_ext.h>
52 ///////////////////////////////////////////////////////
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
);
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.
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
);
94 void ParseJID(const PString
& jid
);
95 void BuildJID() const;
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
);
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
);
128 Stream(Transport
* transport
= 0);
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
149 virtual void Reset();
150 PXMLStreamParser
* GetParser() { return m_Parser
; }
153 PXMLStreamParser
* m_Parser
;
154 PNotifierList m_OpenHandlers
;
155 PNotifierList m_CloseHandlers
;
159 class BaseStreamHandler
: public PThread
161 PCLASSINFO(BaseStreamHandler
, PThread
);
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
);
183 PDECLARE_NOTIFIER(Stream
, BaseStreamHandler
, OnOpen
);
184 PDECLARE_NOTIFIER(Stream
, BaseStreamHandler
, OnClose
);
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
)
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
)
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
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.
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
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
)
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
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.
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
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
)
363 /** Various constant strings
365 static const PString Type
;
367 IQ(IQType type
, PXMLElement
* body
= 0);
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();
411 PNotifierList m_ResponseHandlers
;
421 // End of File ///////////////////////////////////////////////////////////////