00001
00024 #ifndef __YATEJABBER_H
00025 #define __YATEJABBER_H
00026
00027 #include <xmpputils.h>
00028 #include <xmlparser.h>
00029
00033 namespace TelEngine {
00034
00035 class JBEvent;
00036 class JBStream;
00037 class JBComponentStream;
00038 class JBClientStream;
00039 class JBThread;
00040 class JBThreadList;
00041 class JBEngine;
00042 class JBService;
00043 class JBPresence;
00044 class JIDResource;
00045 class JIDResourceList;
00046 class XMPPUser;
00047 class XMPPUserRoster;
00048
00054 class YJINGLE_API JBEvent : public RefObject
00055 {
00056 friend class JBStream;
00057 friend class JBClientStream;
00058 public:
00062 enum Type {
00063
00064 Terminated = 1,
00065 Destroy = 2,
00066 Running = 3,
00067
00068 WriteFail = 10,
00069
00070 Presence = 20,
00071 Message = 30,
00072 Iq = 50,
00073 IqError = 51,
00074 IqResult = 52,
00075
00076 IqDiscoInfoGet = 60,
00077 IqDiscoInfoSet = 61,
00078 IqDiscoInfoRes = 62,
00079 IqDiscoInfoErr = 63,
00080 IqDiscoItemsGet = 64,
00081 IqDiscoItemsSet = 65,
00082 IqDiscoItemsRes = 66,
00083 IqDiscoItemsErr = 67,
00084
00085 IqCommandGet = 70,
00086 IqCommandSet = 71,
00087 IqCommandRes = 72,
00088 IqCommandErr = 73,
00089
00090 IqJingleGet = 80,
00091 IqJingleSet = 81,
00092 IqJingleRes = 82,
00093 IqJingleErr = 83,
00094
00095 IqRosterSet = 91,
00096 IqRosterRes = 92,
00097 IqRosterErr = 93,
00098
00099
00100 IqClientRosterUpdate = 150,
00101
00102 Unhandled = 200,
00103 Invalid = 500,
00104 };
00105
00113 JBEvent(Type type, JBStream* stream, XMLElement* element, XMLElement* child = 0);
00114
00122 JBEvent(Type type, JBStream* stream, XMLElement* element, const String& senderID);
00123
00127 virtual ~JBEvent();
00128
00133 inline int type() const
00134 { return m_type; }
00135
00140 inline const char* name() const
00141 { return lookup(type()); }
00142
00147 inline const String& stanzaType() const
00148 { return m_stanzaType; }
00149
00154 inline const JabberID& from() const
00155 { return m_from; }
00156
00161 inline const JabberID& to() const
00162 { return m_to; }
00163
00169 inline const String& id() const
00170 { return m_id; }
00171
00176 inline const String& text() const
00177 { return m_text; }
00178
00183 inline JBStream* stream() const
00184 { return m_stream; }
00185
00190 inline XMLElement* element() const
00191 { return m_element; }
00192
00197 inline XMLElement* child() const
00198 { return m_child; }
00199
00206 inline XMLElement* releaseXML(bool del = false) {
00207 TelEngine::destruct(m_child);
00208 if (del) {
00209 TelEngine::destruct(m_element);
00210 return 0;
00211 }
00212 XMLElement* tmp = m_element;
00213 m_element = 0;
00214 return tmp;
00215 }
00216
00220 void releaseStream();
00221
00230 XMLElement* createError(XMPPError::ErrorType type, XMPPError::Type error, const char* text = 0);
00231
00236 inline static const char* lookup(int type)
00237 { return TelEngine::lookup(type,s_type); }
00238
00239 private:
00240 static TokenDict s_type[];
00241 JBEvent() {}
00242 bool init(JBStream* stream, XMLElement* element);
00243
00244 Type m_type;
00245 JBStream* m_stream;
00246 bool m_link;
00247 XMLElement* m_element;
00248 XMLElement* m_child;
00249 String m_stanzaType;
00250 JabberID m_from;
00251 JabberID m_to;
00252 String m_id;
00253
00254 String m_text;
00255
00256 };
00257
00262 class YJINGLE_API JBSocket
00263 {
00264 friend class JBStream;
00265 public:
00273 JBSocket(JBEngine* engine, JBStream* stream,
00274 const char* address, int port);
00275
00279 inline ~JBSocket()
00280 { terminate(); }
00281
00286 inline bool valid() const
00287 { return m_socket && m_socket->valid(); }
00288
00293 inline const SocketAddr& addr() const
00294 { return m_address; }
00295
00300 inline const String& error() const
00301 { return m_error; }
00302
00311 bool connect(bool& terminated, const char* newAddr, int newPort = 0);
00312
00317 void terminate(bool shutdown = false);
00318
00326 bool recv(char* buffer, unsigned int& len);
00327
00334 bool send(const char* buffer, unsigned int& len);
00335
00336 private:
00337 JBEngine* m_engine;
00338 JBStream* m_stream;
00339 Socket* m_socket;
00340 String m_remoteDomain;
00341 SocketAddr m_address;
00342 Mutex m_streamMutex;
00343 Mutex m_receiveMutex;
00344 String m_error;
00345 };
00346
00352 class YJINGLE_API JBStream : public RefObject
00353 {
00354 friend class JBEngine;
00355 friend class JBEvent;
00356 public:
00360 enum State {
00361 Idle = 0,
00362 Connecting = 1,
00363 Started = 2,
00364 Securing = 3,
00365 Auth = 4,
00366 Running = 5,
00367 Destroy = 6,
00368 };
00369
00373 enum Error {
00374 ErrorNone = 0,
00375 ErrorContext,
00376 ErrorPending,
00377 ErrorNoSocket,
00378 };
00379
00383 enum Flags {
00384 AutoRestart = 0x0001,
00385 AllowPlainAuth = 0x0002,
00386
00387
00388 NoVersion1 = 0x0004,
00389 UseTls = 0x0008,
00390
00391 UseSasl = 0x0010,
00392
00393 StreamSecured = 0x0100,
00394 StreamAuthenticated = 0x0200,
00395 NoRemoteVersion1 = 0x0400,
00396 };
00397
00402 virtual ~JBStream();
00403
00408 inline int type() const
00409 { return m_type; }
00410
00415 inline State state() const
00416 { return m_state; }
00417
00422 inline bool outgoing() const
00423 { return m_outgoing; }
00424
00429 inline const String& name() const
00430 { return m_name; }
00431
00436 inline const String& id() const
00437 { return m_id; }
00438
00443 inline JBEngine* engine() const
00444 { return m_engine; }
00445
00450 inline const JabberID& local() const
00451 { return m_local; }
00452
00457 inline const JabberID& remote() const
00458 { return m_remote; }
00459
00464 inline const SocketAddr& addr() const
00465 { return m_socket.addr(); }
00466
00472 inline bool flag(int mask) const
00473 { return 0 != (m_flags & mask); }
00474
00479 inline Mutex* streamMutex()
00480 { return &m_socket.m_streamMutex; }
00481
00486 void connect();
00487
00494 bool receive();
00495
00503 virtual Error sendStanza(XMLElement* stanza, const char* senderId = 0);
00504
00513 JBEvent* getEvent(u_int64_t time);
00514
00526 void terminate(bool destroy, XMLElement* recvStanza, XMPPError::Type error, const char* reason,
00527 bool send, bool final = false);
00528
00535 inline void removePending(const String& id, bool notify = false) {
00536 Lock lock(m_socket.m_streamMutex);
00537 removePending(notify,&id,false);
00538 }
00539
00544 virtual const String& toString() const
00545 { return name(); }
00546
00551 virtual void* getObject(const String& name) const;
00552
00558 static const char* lookupState(int state);
00559
00563 static TokenDict s_flagName[];
00564
00565 protected:
00569 enum WaitState {
00570 WaitIdle,
00571 WaitStart,
00572 WaitFeatures,
00573 WaitBindRsp,
00574 WaitTlsRsp,
00575 WaitChallenge,
00576 WaitResponse,
00577 WaitAborted,
00578 };
00579
00588 JBStream(JBEngine* engine, int type, XMPPServerInfo& info,
00589 const JabberID& localJid, const JabberID& remoteJid);
00590
00594 inline JBStream()
00595 : m_socket(0,0,0,0)
00596 {}
00597
00601 virtual void destroyed();
00602
00611 virtual bool checkDestination(XMLElement* xml, bool& respond);
00612
00617 virtual XMLElement* getStreamStart();
00618
00623 virtual XMLElement* getAuthStart();
00624
00629 virtual void processRunning(XMLElement* xml);
00630
00635 virtual void processAuth(XMLElement* xml);
00636
00642 virtual void processSecuring(XMLElement* xml);
00643
00648 virtual void processStarted(XMLElement* xml);
00649
00653 virtual void streamRunning()
00654 {}
00655
00663 JBEvent* getIqEvent(XMLElement* xml, int iqType, XMPPError::Type& error);
00664
00669 bool sendStreamStart();
00670
00677 bool sendStreamXML(XMLElement* e, State newState);
00678
00685 void invalidStreamXML(XMLElement* xml, XMPPError::Type error, const char* reason);
00686
00691 void errorStreamXML(XMLElement* xml);
00692
00698 void dropXML(XMLElement* xml, bool unexpected = true);
00699
00704 void changeState(State newState);
00705
00713 bool getStreamFeatures(XMLElement* features);
00714
00719 bool startTls();
00720
00726 bool startAuth();
00727
00735 bool sendAuthResponse(XMLElement* challenge = 0);
00736
00744 void buildSaslResponse(String& response, String* realm = 0,
00745 String* nonce = 0);
00746
00751 void setClientAuthMechanism();
00752
00759 void buildDigestMD5Sasl(String& dest, bool authenticate = true);
00760
00765 void setRecvCount(int value);
00766
00772 bool startIdleTimer(u_int64_t time = Time::msecNow());
00773
00778 inline JBEvent* lastEvent() {
00779 ObjList* o = m_events.last();
00780 return o ? static_cast<JBEvent*>(o->get()) : 0;
00781 }
00782
00786 String m_name;
00787
00791 String m_password;
00792
00796 JIDFeatureList m_localFeatures;
00797
00801 JIDFeatureList m_remoteFeatures;
00802
00806 int m_flags;
00807
00811 unsigned int m_challengeCount;
00812
00816 WaitState m_waitState;
00817
00821 JIDFeatureSasl::Mechanism m_authMech;
00822
00826 ObjList m_events;
00827
00828 private:
00829
00830
00831 void eventTerminated(const JBEvent* event);
00832
00833
00834
00835 Error sendPending();
00836
00837
00838
00839 void removePending(bool notify, const String* id, bool force);
00840
00841
00842 void resetStream();
00843
00844 int m_type;
00845 State m_state;
00846 bool m_outgoing;
00847 unsigned int m_restart;
00848 unsigned int m_restartMax;
00849 u_int64_t m_timeToFillRestart;
00850 u_int64_t m_setupTimeout;
00851 u_int64_t m_idleTimeout;
00852 String m_id;
00853 JabberID m_local;
00854 JabberID m_remote;
00855 JBEngine* m_engine;
00856 JBSocket m_socket;
00857 XMLParser m_parser;
00858 ObjList m_outXML;
00859 JBEvent* m_lastEvent;
00860 JBEvent* m_terminateEvent;
00861 JBEvent* m_startEvent;
00862 int m_recvCount;
00863 XMLElementOut* m_streamXML;
00864 unsigned int m_declarationSent;
00865
00866 unsigned int m_nonceCount;
00867 String m_nc;
00868 String m_nonce;
00869 String m_cnonce;
00870 String m_realm;
00871 };
00872
00877 class YJINGLE_API JBComponentStream : public JBStream
00878 {
00879 friend class JBEngine;
00880 public:
00884 virtual ~JBComponentStream()
00885 {}
00886
00887 protected:
00895 JBComponentStream(JBEngine* engine, XMPPServerInfo& info,
00896 const JabberID& localJid, const JabberID& remoteJid);
00897
00902 virtual XMLElement* getStreamStart();
00903
00908 virtual XMLElement* getAuthStart();
00909
00914 virtual void processAuth(XMLElement* xml);
00915
00920 virtual void processStarted(XMLElement* xml);
00921
00922 private:
00923
00924 JBComponentStream() {}
00925 };
00926
00931 class YJINGLE_API JBClientStream : public JBStream
00932 {
00933 friend class JBEngine;
00934 public:
00938 virtual ~JBClientStream();
00939
00944 inline XMPPUserRoster* roster()
00945 { return m_roster; }
00946
00951 inline JIDResource* getResource()
00952 { return m_resource; }
00953
00959 XMPPUser* getRemote(const JabberID& jid);
00960
00967 virtual Error sendStanza(XMLElement* stanza, const char* senderId = 0);
00968
00969 protected:
00977 JBClientStream(JBEngine* engine, XMPPServerInfo& info, const JabberID& jid,
00978 const NamedList& params);
00979
00992 JBClientStream(JBEngine* engine, const JabberID& jid,
00993 const String& password, const SocketAddr& address,
00994 bool autoRestart, unsigned int maxRestart, u_int64_t incRestartInterval,
00995 bool allowPlainAuth = false, bool outgoing = true);
00996
01000 virtual void streamRunning();
01001
01006 virtual void processRunning(XMLElement* xml);
01007
01015 virtual bool checkDestination(XMLElement* xml, bool& respond);
01016
01017 private:
01018
01019 JBClientStream() {}
01020
01021 XMPPUserRoster* m_roster;
01022 JIDResource* m_resource;
01023 String m_rosterReqId;
01024 };
01025
01026
01031 class YJINGLE_API JBThread : public GenObject
01032 {
01033 public:
01037 enum Type {
01038 StreamConnect,
01039 EngineReceive,
01040 EngineProcess,
01041
01042 Presence,
01043 Jingle,
01044 Message
01045 };
01046
01050 virtual ~JBThread();
01051
01056 inline Type type() const
01057 { return m_type; }
01058
01064 virtual void cancelThread(bool hard = false) = 0;
01065
01075 static bool start(Type type, JBThreadList* list, void* client, int sleep, int prio);
01076
01077 protected:
01085 JBThread(Type type, JBThreadList* owner, void* client, int sleep = 2);
01086
01090 void runClient();
01091
01096 inline void* client()
01097 { return m_client; }
01098
01099 private:
01100 Type m_type;
01101 JBThreadList* m_owner;
01102 void* m_client;
01103 int m_sleep;
01104 };
01105
01106
01111 class YJINGLE_API JBThreadList
01112 {
01113 friend class JBThread;
01114 public:
01119 inline DebugEnabler* owner() const
01120 { return m_owner; }
01121
01128 void cancelThreads(bool wait = true, bool hard = false);
01129
01130 protected:
01135 JBThreadList(DebugEnabler* owner = 0)
01136 : m_owner(owner), m_mutex(true), m_cancelling(false)
01137 { m_threads.setDelete(false); }
01138
01143 inline void setOwner(DebugEnabler* dbg)
01144 { m_owner = dbg; }
01145
01146 private:
01147 DebugEnabler* m_owner;
01148 Mutex m_mutex;
01149 ObjList m_threads;
01150 bool m_cancelling;
01151 };
01152
01153
01158 class YJINGLE_API JBEngine : public DebugEnabler, public Mutex,
01159 public GenObject, public JBThreadList
01160 {
01161 friend class JBStream;
01162 public:
01166 enum Protocol {
01167 Component = 1,
01168 Client = 2,
01169 };
01170
01174 enum Service {
01175 ServiceJingle = 0,
01176 ServiceIq = 1,
01177 ServiceMessage = 2,
01178 ServicePresence = 3,
01179 ServiceCommand = 4,
01180 ServiceDisco = 5,
01181 ServiceStream = 6,
01182 ServiceWriteFail = 7,
01183 ServiceRoster = 8,
01184 ServiceCount = 9
01185 };
01186
01191 JBEngine(Protocol proto);
01192
01196 virtual ~JBEngine();
01197
01202 inline Protocol protocol() const
01203 { return m_protocol; }
01204
01209 inline const JabberID& componentServer() const
01210 { return m_componentDomain; }
01211
01216 inline void setAlternateDomain(const char* domain = 0)
01217 { m_alternateDomain = domain; }
01218
01223 inline const JabberID& getAlternateDomain() const
01224 { return m_alternateDomain; }
01225
01230 inline const String& defaultResource() const
01231 { return m_defaultResource; }
01232
01237 inline const ObjList& streams() const
01238 { return m_streams; }
01239
01243 virtual void destruct();
01244
01249 virtual void initialize(const NamedList& params);
01250
01254 void cleanup();
01255
01262 void setComponentServer(const char* domain);
01263
01269 JBStream* findStream(const String& name);
01270
01281 JBStream* getStream(const JabberID* jid = 0, bool create = true);
01282
01289 bool getStream(JBStream*& stream, bool& release);
01290
01296 JBClientStream* createClientStream(NamedList& params);
01297
01303 bool receive();
01304
01311 bool process(u_int64_t time);
01312
01318 bool checkDupId(const JBStream* stream);
01319
01326 bool checkComponentFrom(JBComponentStream* stream, const char* from);
01327
01332 virtual void connect(JBStream* stream);
01333
01338 virtual bool exiting() const
01339 { return false; }
01340
01346 virtual bool encryptStream(JBStream* stream);
01347
01353 void appendServer(XMPPServerInfo* server, bool open);
01354
01364 bool getServerIdentity(String& destination, bool full, const char* token = 0,
01365 bool domain = true);
01366
01374 XMPPServerInfo* findServerInfo(const char* token, bool domain);
01375
01384 void attachService(JBService* service, Service type, int prio = -1);
01385
01391 void detachService(JBService* service);
01392
01399 void printXml(const XMLElement& xml, const JBStream* stream, bool send) const;
01400
01405 inline static const char* lookupProto(int proto, const char* def = 0)
01406 { return lookup(proto,s_protoName,def); }
01407
01412 inline static int lookupProto(const char* proto, int def = 0)
01413 { return lookup(proto,s_protoName,def); }
01414
01415 private:
01416
01417 bool processDisco(JBEvent* event);
01418
01419 bool processCommand(JBEvent* event);
01420
01421 bool received(Service service, JBEvent* event);
01422 static TokenDict s_protoName[];
01423
01424 Protocol m_protocol;
01425 u_int32_t m_restartUpdateInterval;
01426 u_int32_t m_restartCount;
01427 u_int64_t m_streamSetupInterval;
01428 u_int64_t m_streamIdleInterval;
01429 int m_printXml;
01430 ObjList m_streams;
01431 JIDIdentity* m_identity;
01432 JIDFeatureList m_features;
01433 JabberID m_componentDomain;
01434 String m_componentAddr;
01435 int m_componentCheckFrom;
01436
01437 JabberID m_alternateDomain;
01438 String m_defaultResource;
01439 Mutex m_serverMutex;
01440 ObjList m_server;
01441 Mutex m_servicesMutex;
01442 ObjList m_services[ServiceCount];
01443 bool m_initialized;
01444 };
01445
01446
01452 class YJINGLE_API JBService : public DebugEnabler, public Mutex, public GenObject
01453 {
01454 public:
01462 JBService(JBEngine* engine, const char* name, const NamedList* params, int prio);
01463
01467 virtual ~JBService();
01468
01473 inline JBEngine* engine()
01474 { return m_engine; }
01475
01480 inline int priority() const
01481 { return m_priority; }
01482
01491 bool received(JBEvent* event);
01492
01497 virtual void initialize(const NamedList& params)
01498 {}
01499
01503 virtual void destruct();
01504
01505 protected:
01514 virtual bool accept(JBEvent* event, bool& processed, bool& insert);
01515
01520 JBEvent* deque();
01521
01525 bool m_initialized;
01526
01527 private:
01528 inline JBService() {}
01529 JBEngine* m_engine;
01530 int m_priority;
01531 ObjList m_events;
01532 };
01533
01534
01539 class YJINGLE_API JBMessage : public JBService, public JBThreadList
01540 {
01541 public:
01545 enum MsgType {
01546 Chat,
01547 GroupChat,
01548 HeadLine,
01549 Normal,
01550 Error,
01551 None,
01552 };
01553
01560 inline JBMessage(JBEngine* engine, const NamedList* params, int prio = 0)
01561 : JBService(engine,"jbmsgrecv",params,prio), m_syncProcess(true)
01562 { JBThreadList::setOwner(this); }
01563
01567 virtual ~JBMessage()
01568 { cancelThreads(); }
01569
01574 virtual void initialize(const NamedList& params);
01575
01580 inline JBEvent* getMessage()
01581 { return deque(); }
01582
01588 virtual void processMessage(JBEvent* event);
01589
01599 static XMLElement* createMessage(MsgType type, const char* from,
01600 const char* to, const char* id, const char* message);
01601
01607 static inline MsgType msgType(const char* text)
01608 { return (MsgType)lookup(text,s_msg,None); }
01609
01615 static inline const char* msgText(MsgType msg)
01616 { return lookup(msg,s_msg,0); }
01617
01621 static TokenDict s_msg[];
01622
01623 protected:
01631 virtual bool accept(JBEvent* event, bool& processed, bool& insert);
01632
01633 private:
01634 bool m_syncProcess;
01635 };
01636
01637
01643 class YJINGLE_API JBPresence : public JBService, public JBThreadList
01644 {
01645 friend class XMPPUserRoster;
01646 public:
01650 enum Presence {
01651 Error = 0,
01652 Probe = 1,
01653 Subscribe = 2,
01654 Subscribed = 3,
01655 Unavailable = 4,
01656 Unsubscribe = 5,
01657 Unsubscribed = 6,
01658 None = 7,
01659 };
01660
01667 JBPresence(JBEngine* engine, const NamedList* params, int prio = 0);
01668
01672 virtual ~JBPresence();
01673
01678 inline XMPPDirVal autoSubscribe() const
01679 { return m_autoSubscribe; }
01680
01685 inline bool delUnavailable() const
01686 { return m_delUnavailable; }
01687
01692 inline XMPPDirVal addOnSubscribe() const
01693 { return m_addOnSubscribe; }
01694
01699 inline XMPPDirVal addOnProbe() const
01700 { return m_addOnProbe; }
01701
01706 inline XMPPDirVal addOnPresence() const
01707 { return m_addOnPresence; }
01708
01713 inline bool autoRoster() const
01714 { return m_autoRoster; }
01715
01720 inline bool ignoreNonRoster() const
01721 { return m_ignoreNonRoster; }
01722
01727 inline u_int32_t probeInterval()
01728 { return m_probeInterval; }
01729
01734 inline u_int32_t expireInterval()
01735 { return m_expireInterval; }
01736
01741 virtual void initialize(const NamedList& params);
01742
01748 virtual bool process();
01749
01755 virtual void checkTimeout(u_int64_t time);
01756
01761 virtual void processDisco(JBEvent* event);
01762
01767 virtual void processError(JBEvent* event);
01768
01773 virtual void processProbe(JBEvent* event);
01774
01780 virtual void processSubscribe(JBEvent* event, Presence presence);
01781
01786 virtual void processUnavailable(JBEvent* event);
01787
01792 virtual void processPresence(JBEvent* event);
01793
01799 virtual bool notifyProbe(JBEvent* event);
01800
01807 virtual bool notifySubscribe(JBEvent* event, Presence presence);
01808
01814 virtual void notifySubscribe(XMPPUser* user, Presence presence);
01815
01823 virtual bool notifyPresence(JBEvent* event, bool available);
01824
01830 virtual void notifyPresence(XMPPUser* user, JIDResource* resource);
01831
01837 virtual void notifyNewUser(XMPPUser* user);
01838
01847 XMPPUserRoster* getRoster(const JabberID& jid, bool add, bool* added);
01848
01860 XMPPUser* getRemoteUser(const JabberID& local, const JabberID& remote,
01861 bool addLocal, bool* addedLocal, bool addRemote, bool* addedRemote);
01862
01869 void removeRemoteUser(const JabberID& local, const JabberID& remote);
01870
01876 bool validDomain(const String& domain);
01877
01886 bool sendStanza(XMLElement* element, JBStream* stream);
01887
01899 bool sendError(XMPPError::Type type, const String& from, const String& to,
01900 XMLElement* element, JBStream* stream = 0, const String* id = 0);
01901
01909 static XMLElement* createPresence(const char* from,
01910 const char* to, Presence type = None);
01911
01920 static bool decodeError(const XMLElement* element,
01921 String& code, String& type, String& error);
01922
01928 static inline Presence presenceType(const char* text)
01929 { return (Presence)lookup(text,s_presence,None); }
01930
01936 static inline const char* presenceText(Presence presence)
01937 { return lookup(presence,s_presence,0); }
01938
01942 void cleanup();
01943
01944 protected:
01952 virtual bool accept(JBEvent* event, bool& processed, bool& insert);
01953
01954 static TokenDict s_presence[];
01955 XMPPDirVal m_autoSubscribe;
01956 bool m_delUnavailable;
01957 bool m_autoRoster;
01958 bool m_ignoreNonRoster;
01959 XMPPDirVal m_addOnSubscribe;
01960 XMPPDirVal m_addOnProbe;
01961 XMPPDirVal m_addOnPresence;
01962 bool m_autoProbe;
01963 u_int32_t m_probeInterval;
01964 u_int32_t m_expireInterval;
01965 ObjList m_rosters;
01966 JIDIdentity* m_defIdentity;
01967 JIDFeatureList m_defFeatures;
01968
01969 private:
01970
01971
01972 XMPPUser* recvGetRemoteUser(const char* type, const JabberID& local, const JabberID& remote,
01973 bool addLocal = false, bool* addedLocal = 0,
01974 bool addRemote = false, bool* addedRemote = 0);
01975 void addRoster(XMPPUserRoster* ur);
01976 void removeRoster(XMPPUserRoster* ur);
01977 };
01978
01979
01984 class YJINGLE_API JIDResource : public RefObject
01985 {
01986 public:
01990 enum Capability {
01991 CapChat = 1,
01992 CapAudio = 2,
01993 };
01994
01998 enum Presence {
01999 Unknown = 0,
02000 Available = 1,
02001 Unavailable = 2,
02002 };
02003
02007 enum Show {
02008 ShowAway,
02009 ShowChat,
02010 ShowDND,
02011 ShowXA,
02012 ShowNone,
02013 };
02014
02021 inline JIDResource(const char* name, Presence presence = Unknown,
02022 u_int32_t capability = CapChat)
02023 : m_name(name), m_presence(presence),
02024 m_capability(capability), m_show(ShowNone)
02025 {}
02026
02030 inline virtual ~JIDResource()
02031 {}
02032
02037 inline const String& name() const
02038 { return m_name; }
02039
02044 inline void setName(const char* name)
02045 { m_name = name; }
02046
02051 inline Presence presence() const
02052 { return m_presence; }
02053
02058 inline bool available() const
02059 { return (m_presence == Available); }
02060
02065 inline Show show() const
02066 { return m_show; }
02067
02072 inline void show(Show s)
02073 { m_show = s; }
02074
02079 inline const String& status() const
02080 { return m_status; }
02081
02086 inline void status(const char* s)
02087 { m_status = s; }
02088
02093 inline ObjList* infoXml()
02094 { return &m_info; }
02095
02101 bool setPresence(bool value);
02102
02108 inline bool hasCap(Capability capability) const
02109 { return (m_capability & capability) != 0; }
02110
02116 bool fromXML(XMLElement* element);
02117
02123 void addTo(XMLElement* element, bool addInfo = true);
02124
02130 static const char* getShow(XMLElement* element);
02131
02137 static const char* getStatus(XMLElement* element);
02138
02144 static inline Show showType(const char* text)
02145 { return (Show)lookup(text,s_show,ShowNone); }
02146
02152 static inline const char* showText(Show show)
02153 { return lookup(show,s_show,0); }
02154
02155 protected:
02156 static TokenDict s_show[];
02157
02158 private:
02159 String m_name;
02160 Presence m_presence;
02161 u_int32_t m_capability;
02162 Show m_show;
02163 String m_status;
02164 ObjList m_info;
02165 };
02166
02167
02172 class YJINGLE_API JIDResourceList : public Mutex
02173 {
02174 friend class XMPPUser;
02175 friend class JBPresence;
02176 public:
02180 inline JIDResourceList()
02181 : Mutex(true)
02182 {}
02183
02190 bool add(const String& name);
02191
02198 bool add(JIDResource* resource);
02199
02205 inline void remove(JIDResource* resource, bool del = true)
02206 { Lock lock(this); m_resources.remove(resource,del); }
02207
02211 inline void clear()
02212 { Lock lock(this); m_resources.clear(); }
02213
02219 JIDResource* get(const String& name);
02220
02225 inline JIDResource* getFirst() {
02226 Lock lock(this);
02227 ObjList* obj = m_resources.skipNull();
02228 return obj ? static_cast<JIDResource*>(obj->get()) : 0;
02229 }
02230
02236 JIDResource* getAudio(bool availableOnly = true);
02237
02238 private:
02239 ObjList m_resources;
02240 };
02241
02242
02247 class YJINGLE_API XMPPUser : public RefObject, public Mutex
02248 {
02249 friend class XMPPUserRoster;
02250 friend class JBPresence;
02251 public:
02261 XMPPUser(XMPPUserRoster* local, const char* node, const char* domain,
02262 XMPPDirVal sub, bool subTo = true, bool sendProbe = true);
02263
02268 virtual ~XMPPUser();
02269
02274 inline const JabberID& jid() const
02275 { return m_jid; }
02276
02281 inline XMPPUserRoster* local() const
02282 { return m_local; }
02283
02288 inline XMPPDirVal& subscription()
02289 { return m_subscription; }
02290
02295 inline JIDResourceList& localRes()
02296 { return m_localRes; }
02297
02302 inline JIDResourceList& remoteRes()
02303 { return m_remoteRes; }
02304
02313 bool addLocalRes(JIDResource* resource, bool send = true);
02314
02321 void removeLocalRes(JIDResource* resource);
02322
02328 void clearLocalRes();
02329
02335 bool addRemoteRes(JIDResource* resource);
02336
02341 void removeRemoteRes(JIDResource* resource);
02342
02349 inline JIDResource* getAudio(bool local, bool availableOnly = true) {
02350 return local ? m_localRes.getAudio(availableOnly) :
02351 m_remoteRes.getAudio(availableOnly);
02352 }
02353
02359 void processError(JBEvent* event);
02360
02367 void processProbe(JBEvent* event, const String* resName = 0);
02368
02376 bool processPresence(JBEvent* event, bool available);
02377
02384 void processSubscribe(JBEvent* event, JBPresence::Presence type);
02385
02393 bool probe(JBStream* stream, u_int64_t time = Time::msecNow());
02394
02402 bool sendSubscribe(JBPresence::Presence type, JBStream* stream);
02403
02410 bool sendUnavailable(JBStream* stream);
02411
02420 bool sendPresence(JIDResource* resource, JBStream* stream = 0, bool force = false);
02421
02428 bool timeout(u_int64_t time);
02429
02439 void notifyResource(bool remote, const String& name,
02440 JBStream* stream = 0, bool force = false);
02441
02450 void notifyResources(bool remote, JBStream* stream = 0, bool force = false);
02451
02452 protected:
02459 void updateSubscription(bool from, bool value, JBStream* stream);
02460
02466 void updateTimeout(bool from, u_int64_t time = Time::msecNow());
02467
02468 private:
02469 XMPPUserRoster* m_local;
02470 JabberID m_jid;
02471 XMPPDirVal m_subscription;
02472 JIDResourceList m_localRes;
02473 JIDResourceList m_remoteRes;
02474 u_int64_t m_nextProbe;
02475 u_int64_t m_expire;
02476 };
02477
02482 class YJINGLE_API XMPPUserRoster : public RefObject, public Mutex
02483 {
02484 friend class JBPresence;
02485 friend class JBClientStream;
02486 friend class XMPPUser;
02487 public:
02492 virtual ~XMPPUserRoster();
02493
02498 const JabberID& jid() const
02499 { return m_jid; }
02500
02505 JBPresence* engine()
02506 { return m_engine; }
02507
02512 inline JIDResourceList& resources()
02513 { return m_resources; }
02514
02523 XMPPUser* getUser(const JabberID& jid, bool add = false, bool* added = 0);
02524
02531 bool removeUser(const JabberID& remote);
02532
02536 inline void cleanup() {
02537 Lock lock(this);
02538 m_remote.clear();
02539 }
02540
02547 bool timeout(u_int64_t time);
02548
02556 inline XMLElement* createDiscoInfoResult(const char* from, const char* to,
02557 const char* id)
02558 { return XMPPUtils::createDiscoInfoRes(from,to,id,&m_features,m_identity); }
02559
02560 protected:
02568 XMPPUserRoster(JBPresence* engine, const char* node, const char* domain,
02569 JBEngine::Protocol proto = JBEngine::Component);
02570
02571 private:
02572 inline void addUser(XMPPUser* u) {
02573 Lock lock(this);
02574 m_remote.append(u);
02575 }
02576 void removeUser(XMPPUser* u) {
02577 Lock lock(this);
02578 m_remote.remove(u,false);
02579 }
02580
02581 JabberID m_jid;
02582 JIDFeatureList m_features;
02583 JIDIdentity* m_identity;
02584 ObjList m_remote;
02585 JIDResourceList m_resources;
02586 JBPresence* m_engine;
02587 };
02588
02589 };
02590
02591 #endif
02592
02593