00001
00024 #ifndef __XMPPUTILS_H
00025 #define __XMPPUTILS_H
00026
00027 #include <yateclass.h>
00028 #include <xmlparser.h>
00029
00030 #ifdef _WINDOWS
00031
00032 #ifdef LIBYJINGLE_EXPORTS
00033 #define YJINGLE_API __declspec(dllexport)
00034 #else
00035 #ifndef LIBYJINGLE_STATIC
00036 #define YJINGLE_API __declspec(dllimport)
00037 #endif
00038 #endif
00039
00040 #endif
00041
00042 #ifndef YJINGLE_API
00043 #define YJINGLE_API
00044 #endif
00045
00049 namespace TelEngine {
00050
00051 class XMPPServerInfo;
00052 class XMPPNamespace;
00053 class XMPPError;
00054 class JabberID;
00055 class JIDIdentity;
00056 class JIDFeature;
00057 class JIDFeatureSasl;
00058 class JIDFeatureList;
00059 class XMPPUtils;
00060 class XMPPDirVal;
00061
00066 class YJINGLE_API XMPPServerInfo : public RefObject
00067 {
00068 public:
00072 enum ServerFlag {
00073 NoAutoRestart = 0x0001,
00074 KeepRoster = 0x0002,
00075 TlsRequired = 0x0004,
00076 OldStyleAuth = 0x0008,
00077 AllowPlainAuth = 0x0020,
00078 };
00079
00090 inline XMPPServerInfo(const char* name, const char* address, int port,
00091 const char* password, const char* identity, const char* fullidentity,
00092 int flags)
00093 : m_name(name), m_address(address), m_port(port), m_password(password),
00094 m_identity(identity), m_fullIdentity(fullidentity), m_flags(flags)
00095 {}
00096
00102 inline XMPPServerInfo(const char* name, int port)
00103 : m_name(name), m_port(port)
00104 {}
00105
00110 inline const String& address() const
00111 { return m_address; }
00112
00117 inline const String& name() const
00118 { return m_name; }
00119
00124 inline const int port() const
00125 { return m_port; }
00126
00131 inline const String& password() const
00132 { return m_password; }
00133
00138 inline const String& identity() const
00139 { return m_identity; }
00140
00145 inline const String& fullIdentity() const
00146 { return m_fullIdentity; }
00147
00152 inline bool flag(int mask) const
00153 { return 0 != (m_flags & mask); }
00154
00158 static TokenDict s_flagName[];
00159
00160 private:
00161 String m_name;
00162 String m_address;
00163 int m_port;
00164 String m_password;
00165 String m_identity;
00166 String m_fullIdentity;
00167 int m_flags;
00168 };
00169
00170
00175 class YJINGLE_API XMPPNamespace
00176 {
00177 public:
00178 enum Type {
00179 Stream,
00180 Client,
00181 Server,
00182 ComponentAccept,
00183 ComponentConnect,
00184 StreamError,
00185 StanzaError,
00186 Register,
00187 IqAuth,
00188 IqAuthFeature,
00189 Starttls,
00190 Sasl,
00191 Session,
00192 Bind,
00193 Roster,
00194 DiscoInfo,
00195 DiscoItems,
00196 Jingle,
00197 JingleAudio,
00198 JingleTransport,
00199 Dtmf,
00200 DtmfError,
00201 Command,
00202 CapVoiceV1,
00203 Count,
00204 };
00205
00209 inline const char* operator[](Type index)
00210 { return lookup(index,s_value); }
00211
00215 static bool isText(Type index, const char* txt);
00216
00220 static inline Type type(const char* txt) {
00221 int tmp = lookup(txt,s_value,Count);
00222 return tmp ? (Type)tmp : Count;
00223 }
00224
00225 private:
00226 static TokenDict s_value[];
00227 };
00228
00229
00234 class YJINGLE_API XMPPError
00235 {
00236 public:
00240 enum Type {
00241 NoError = 0,
00242
00243 BadFormat,
00244 BadNamespace,
00245 ConnTimeout,
00246 HostGone,
00247 HostUnknown,
00248 BadAddressing,
00249 Internal,
00250 InvalidFrom,
00251 InvalidId,
00252 InvalidNamespace,
00253 InvalidXml,
00254 NotAuth,
00255 Policy,
00256 RemoteConn,
00257 ResConstraint,
00258 RestrictedXml,
00259 SeeOther,
00260 Shutdown,
00261 UndefinedCondition,
00262 UnsupportedEnc,
00263 UnsupportedStanza,
00264 UnsupportedVersion,
00265 Xml,
00266
00267 Aborted,
00268 IncorrectEnc,
00269 InvalidAuth,
00270 InvalidMechanism,
00271 MechanismTooWeak,
00272 NotAuthorized,
00273 TempAuthFailure,
00274
00275 SBadRequest,
00276 SConflict,
00277 SFeatureNotImpl,
00278 SForbidden,
00279 SGone,
00280 SInternal,
00281 SItemNotFound,
00282 SBadJid,
00283 SNotAcceptable,
00284 SNotAllowed,
00285 SPayment,
00286 SUnavailable,
00287 SRedirect,
00288 SReg,
00289 SNoRemote,
00290 SRemoteTimeout,
00291 SResource,
00292 SServiceUnavailable,
00293 SSubscription,
00294 SUndefinedCondition,
00295 SRequest,
00296
00297 DtmfNoMethod,
00298 Count,
00299 };
00300
00304 enum ErrorType {
00305 TypeCancel = 1000,
00306 TypeContinue,
00307 TypeModify,
00308 TypeAuth,
00309 TypeWait,
00310 TypeCount,
00311 };
00312
00316 inline const char* operator[](int index)
00317 { return lookup(index,s_value); }
00318
00322 static bool isText(int index, const char* txt);
00323
00327 static inline int type(const char* txt)
00328 { return lookup(txt,s_value,Count); }
00329
00330 private:
00331 static TokenDict s_value[];
00332 };
00333
00334
00339 class YJINGLE_API JabberID : public String
00340 {
00341 public:
00345 inline JabberID() {}
00346
00351 inline JabberID(const char* jid)
00352 { set(jid); }
00353
00360 JabberID(const char* node, const char* domain, const char* resource = 0)
00361 { set(node,domain,resource); }
00362
00367 inline const String& node() const
00368 { return m_node; }
00369
00374 inline const String& bare() const
00375 { return m_bare; }
00376
00381 inline const String& domain() const
00382 { return m_domain; }
00383
00388 inline void domain(const char* d)
00389 { set(m_node.c_str(),d,m_resource.c_str()); }
00390
00395 inline const String& resource() const
00396 { return m_resource; }
00397
00402 inline bool isFull() const
00403 { return m_node && m_domain && m_resource; }
00404
00411 inline bool match(const JabberID& src) const
00412 { return (src.resource().null() || (resource() == src.resource())) && (bare() &= src.bare()); }
00413
00419 inline bool operator==(const JabberID& src) const
00420 { return (resource() == src.resource()) && (bare() &= src.bare()); }
00421
00427 inline bool operator==(const String& src) const
00428 { JabberID tmp(src); return operator==(tmp); }
00429
00435 inline bool operator!=(const JabberID& src) const
00436 { return !operator==(src); }
00437
00443 inline bool operator!=(const String& src) const
00444 { return !operator==(src); }
00445
00450 inline void resource(const char* res)
00451 { set(m_node.c_str(),m_domain.c_str(),res); }
00452
00457 void set(const char* jid);
00458
00465 void set(const char* node, const char* domain, const char* resource = 0);
00466
00472 static bool valid(const String& value);
00473
00477 static Regexp s_regExpValid;
00478
00479 private:
00480 void parse();
00481
00482 String m_node;
00483 String m_domain;
00484 String m_resource;
00485 String m_bare;
00486 };
00487
00488
00493 class YJINGLE_API JIDIdentity : public RefObject
00494 {
00495 public:
00499 enum Category {
00500 Account,
00501 Client,
00502 Component,
00503 Gateway,
00504 CategoryUnknown
00505 };
00506
00510 enum Type {
00511 AccountRegistered,
00512 ClientPhone,
00513 ComponentGeneric,
00514 ComponentPresence,
00515 GatewayGeneric,
00516 TypeUnknown
00517 };
00518
00525 inline JIDIdentity(Category c, Type t, const char* name = 0)
00526 : m_name(name), m_category(c), m_type(t)
00527 {}
00528
00532 virtual ~JIDIdentity()
00533 {}
00534
00539 XMLElement* toXML();
00540
00545 bool fromXML(const XMLElement* element);
00546
00551 virtual const String& toString() const
00552 { return m_name; }
00553
00559 virtual void* getObject(const String& name) const {
00560 if (name == "JIDIdentity")
00561 return (void*)this;
00562 return RefObject::getObject(name);
00563 }
00564
00569 inline void setName(const char* name)
00570 { if (name) m_name = name; }
00571
00576 static inline const char* categoryText(Category c)
00577 { return lookup(c,s_category); }
00578
00583 static inline Category categoryValue(const char* c)
00584 { return (Category)lookup(c,s_category,CategoryUnknown); }
00585
00590 static inline const char* typeText(Type t)
00591 { return lookup(t,s_type); }
00592
00597 static inline Type typeValue(const char* t)
00598 { return (Type)lookup(t,s_category,TypeUnknown); }
00599
00600 private:
00601 static TokenDict s_category[];
00602 static TokenDict s_type[];
00603
00604 String m_name;
00605 Category m_category;
00606 Type m_type;
00607 };
00608
00609
00614 class YJINGLE_API JIDFeature : public RefObject
00615 {
00616 public:
00622 inline JIDFeature(XMPPNamespace::Type feature, bool required = false)
00623 : m_feature(feature),
00624 m_required(required)
00625 {}
00626
00630 virtual ~JIDFeature()
00631 {}
00632
00637 inline bool required() const
00638 { return m_required; }
00639
00643 inline operator XMPPNamespace::Type()
00644 { return m_feature; }
00645
00646 private:
00647 XMPPNamespace::Type m_feature;
00648 bool m_required;
00649 };
00650
00651
00656 class YJINGLE_API JIDFeatureSasl : public JIDFeature
00657 {
00658 public:
00662 enum Mechanism {
00663 MechNone = 0x00,
00664 MechMD5 = 0x01,
00665 MechSHA1 = 0x02,
00666 MechPlain = 0x04,
00667 };
00668
00674 inline JIDFeatureSasl(int mech, bool required = false)
00675 : JIDFeature(XMPPNamespace::Sasl,required),
00676 m_mechanism(mech)
00677 {}
00678
00683 inline int mechanism() const
00684 { return m_mechanism; }
00685
00690 inline bool mechanism(Mechanism mech) const
00691 { return 0 != (m_mechanism & mech); }
00692
00696 inline operator XMPPNamespace::Type()
00697 { return JIDFeature::operator XMPPNamespace::Type(); }
00698
00702 static TokenDict s_authMech[];
00703
00704 private:
00705 int m_mechanism;
00706 };
00707
00708
00713 class YJINGLE_API JIDFeatureList
00714 {
00715 public:
00722 inline bool add(XMPPNamespace::Type feature, bool required = false) {
00723 if (get(feature))
00724 return false;
00725 m_features.append(new JIDFeature(feature,required));
00726 return true;
00727 }
00728
00734 inline bool add(JIDFeature* feature) {
00735 if (!feature || get(*feature)) {
00736 TelEngine::destruct(feature);
00737 return false;
00738 }
00739 m_features.append(feature);
00740 return true;
00741 }
00742
00747 inline void remove(XMPPNamespace::Type feature)
00748 { m_features.remove(get(feature),true); }
00749
00755 JIDFeature* get(XMPPNamespace::Type feature);
00756
00762 XMLElement* addTo(XMLElement* element);
00763
00767 inline void clear()
00768 { m_features.clear(); }
00769
00770 private:
00771 ObjList m_features;
00772 };
00773
00778 class YJINGLE_API XMPPUtils
00779 {
00780 public:
00784 enum IqType {
00785 IqSet,
00786 IqGet,
00787 IqResult,
00788 IqError,
00789 IqCount,
00790 };
00791
00795 enum CommandAction {
00796 CommExecute,
00797 CommCancel,
00798 CommPrev,
00799 CommNext,
00800 CommComplete,
00801 };
00802
00806 enum CommandStatus {
00807 CommExecuting,
00808 CommCompleted,
00809 CommCancelled,
00810 };
00811
00819 static XMLElement* createElement(const char* name, XMPPNamespace::Type ns,
00820 const char* text = 0);
00821
00829 static XMLElement* createElement(XMLElement::Type type, XMPPNamespace::Type ns,
00830 const char* text = 0);
00831
00840 static XMLElement* createIq(IqType type, const char* from,
00841 const char* to, const char* id);
00842
00851 static XMLElement* createIqBind(const char* from,
00852 const char* to, const char* id, const ObjList& resources);
00853
00861 static XMLElement* createCommand(CommandAction action, const char* node,
00862 const char* sessionId = 0);
00863
00871 static XMLElement* createIdentity(const char* category,
00872 const char* type, const char* name);
00873
00882 static XMLElement* createIqDisco(const char* from, const char* to,
00883 const char* id, bool info = true);
00884
00895 static XMLElement* createDiscoInfoRes(const char* from, const char* to,
00896 const char* id, JIDFeatureList* features, JIDIdentity* identity);
00897
00905 static XMLElement* createError(XMPPError::ErrorType type,
00906 XMPPError::Type error, const char* text = 0);
00907
00917 static XMLElement* createError(XMLElement* xml, XMPPError::ErrorType type,
00918 XMPPError::Type error, const char* text = 0);
00919
00926 static XMLElement* createStreamError(XMPPError::Type error,
00927 const char* text = 0);
00928
00935 static bool hasXmlns(XMLElement& element, XMPPNamespace::Type ns);
00936
00943 static void decodeError(XMLElement* element, String& error, String& text);
00944
00951 static void print(String& xmlStr, XMLElement& element, const char* indent = 0);
00952
00962 static bool split(NamedList& dest, const char* src, const char sep,
00963 bool nameFirst);
00964
00971 static int decodeFlags(const String& src, const TokenDict* dict);
00972
00979 static void buildFlags(String& dest, int src, const TokenDict* dict);
00980
00987 static bool addChidren(XMLElement* dest, ObjList& list);
00988
00994 static inline IqType iqType(const char* text)
00995 { return (IqType)lookup(text,s_iq,IqCount); }
00996
01000 static TokenDict s_iq[];
01001
01005 static TokenDict s_commandAction[];
01006
01010 static TokenDict s_commandStatus[];
01011 };
01012
01017 class YJINGLE_API XMPPDirVal
01018 {
01019 public:
01020 enum Direction {
01021 None = 0,
01022 To = 1,
01023 From = 2,
01024 Both = 3,
01025 };
01026
01031 inline XMPPDirVal(int flags = None)
01032 : m_value(flags)
01033 {}
01034
01039 inline XMPPDirVal(const char* name)
01040 : m_value(lookup(name,None))
01041 {}
01042
01047 inline void replace(int flag)
01048 { m_value = flag; }
01049
01054 inline void replace(const char* name)
01055 { m_value = lookup(name,None); }
01056
01061 inline void set(int flag)
01062 { m_value |= flag; }
01063
01068 inline void reset(int flag)
01069 { m_value &= ~flag; }
01070
01076 inline bool flag(int mask) const
01077 { return (m_value & mask) != 0; }
01078
01083 inline bool to() const
01084 { return flag(To); }
01085
01090 inline bool from() const
01091 { return flag(From); }
01092
01096 inline operator int()
01097 { return m_value; }
01098
01105 static inline const char* lookup(int flag, const char* defVal = "")
01106 { return TelEngine::lookup(flag,s_names,defVal); }
01107
01114 static inline int lookup(const char* name, int defVal = None)
01115 { return TelEngine::lookup(name,s_names,defVal); }
01116
01120 static TokenDict s_names[];
01121
01122 private:
01123 int m_value;
01124 };
01125
01126 };
01127
01128 #endif
01129
01130