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 AllowUnsafeSetup = 0x0040,
00079 };
00080
00091 inline XMPPServerInfo(const char* name, const char* address, int port,
00092 const char* password, const char* identity, const char* fullidentity,
00093 int flags)
00094 : m_name(name), m_address(address), m_port(port), m_password(password),
00095 m_identity(identity), m_fullIdentity(fullidentity), m_flags(flags)
00096 {}
00097
00103 inline XMPPServerInfo(const char* name, int port)
00104 : m_name(name), m_port(port)
00105 {}
00106
00111 inline const String& address() const
00112 { return m_address; }
00113
00118 inline const String& name() const
00119 { return m_name; }
00120
00125 inline const int port() const
00126 { return m_port; }
00127
00132 inline const String& password() const
00133 { return m_password; }
00134
00139 inline const String& identity() const
00140 { return m_identity; }
00141
00146 inline const String& fullIdentity() const
00147 { return m_fullIdentity; }
00148
00153 inline bool flag(int mask) const
00154 { return 0 != (m_flags & mask); }
00155
00159 static TokenDict s_flagName[];
00160
00161 private:
00162 String m_name;
00163 String m_address;
00164 int m_port;
00165 String m_password;
00166 String m_identity;
00167 String m_fullIdentity;
00168 int m_flags;
00169 };
00170
00171
00176 class YJINGLE_API XMPPNamespace
00177 {
00178 public:
00179 enum Type {
00180 Stream = 1,
00181 Client,
00182 Server,
00183 ComponentAccept,
00184 ComponentConnect,
00185 StreamError,
00186 StanzaError,
00187 Register,
00188 IqRegister,
00189 IqPrivate,
00190 IqAuth,
00191 IqAuthFeature,
00192 Starttls,
00193 Sasl,
00194 Session,
00195 Bind,
00196 Roster,
00197 DynamicRoster,
00198 DiscoInfo,
00199 DiscoItems,
00200 VCard,
00201 SIProfileFileTransfer,
00202 ByteStreams,
00203 Jingle,
00204 JingleError,
00205 JingleAppsRtp,
00206 JingleAppsRtpInfo,
00207 JingleAppsRtpAudio,
00208 JingleAppsFileTransfer,
00209 JingleTransportIceUdp,
00210 JingleTransportRawUdp,
00211 JingleTransportRawUdpInfo,
00212 JingleTransportByteStreams,
00213 JingleTransfer,
00214 Dtmf,
00215 JingleSession,
00216 JingleAudio,
00217 JingleTransport,
00218 JingleRtpInfoOld,
00219 DtmfOld,
00220 Command,
00221 CapVoiceV1,
00222 Count,
00223 };
00224
00228 inline const char* operator[](Type index)
00229 { return lookup(index,s_value); }
00230
00234 static bool isText(Type index, const char* txt);
00235
00239 static inline Type type(const char* txt) {
00240 int tmp = lookup(txt,s_value,Count);
00241 return tmp ? (Type)tmp : Count;
00242 }
00243
00244 private:
00245 static TokenDict s_value[];
00246 };
00247
00248
00253 class YJINGLE_API XMPPError
00254 {
00255 public:
00259 enum Type {
00260 NoError = 0,
00261
00262 BadFormat,
00263 BadNamespace,
00264 ConnTimeout,
00265 HostGone,
00266 HostUnknown,
00267 BadAddressing,
00268 Internal,
00269 InvalidFrom,
00270 InvalidId,
00271 InvalidNamespace,
00272 InvalidXml,
00273 NotAuth,
00274 Policy,
00275 RemoteConn,
00276 ResConstraint,
00277 RestrictedXml,
00278 SeeOther,
00279 Shutdown,
00280 UndefinedCondition,
00281 UnsupportedEnc,
00282 UnsupportedStanza,
00283 UnsupportedVersion,
00284 Xml,
00285
00286 Aborted,
00287 IncorrectEnc,
00288 InvalidAuth,
00289 InvalidMechanism,
00290 MechanismTooWeak,
00291 NotAuthorized,
00292 TempAuthFailure,
00293
00294 SBadRequest,
00295 SConflict,
00296 SFeatureNotImpl,
00297 SForbidden,
00298 SGone,
00299 SInternal,
00300 SItemNotFound,
00301 SBadJid,
00302 SNotAcceptable,
00303 SNotAllowed,
00304 SPayment,
00305 SUnavailable,
00306 SRedirect,
00307 SReg,
00308 SNoRemote,
00309 SRemoteTimeout,
00310 SResource,
00311 SServiceUnavailable,
00312 SSubscription,
00313 SUndefinedCondition,
00314 SRequest,
00315
00316 DtmfNoMethod,
00317 ItemNotFound,
00318 Count,
00319 };
00320
00324 enum ErrorType {
00325 TypeCancel = 1000,
00326 TypeContinue,
00327 TypeModify,
00328 TypeAuth,
00329 TypeWait,
00330 TypeCount,
00331 };
00332
00336 inline const char* operator[](int index)
00337 { return lookup(index,s_value); }
00338
00342 static bool isText(int index, const char* txt);
00343
00347 static inline int type(const char* txt)
00348 { return lookup(txt,s_value,Count); }
00349
00350 private:
00351 static TokenDict s_value[];
00352 };
00353
00354
00359 class YJINGLE_API JabberID : public String
00360 {
00361 public:
00365 inline JabberID() {}
00366
00371 inline JabberID(const char* jid)
00372 { set(jid); }
00373
00380 JabberID(const char* node, const char* domain, const char* resource = 0)
00381 { set(node,domain,resource); }
00382
00387 inline const String& node() const
00388 { return m_node; }
00389
00394 inline const String& bare() const
00395 { return m_bare; }
00396
00401 inline const String& domain() const
00402 { return m_domain; }
00403
00408 inline void domain(const char* d)
00409 { set(m_node.c_str(),d,m_resource.c_str()); }
00410
00415 inline const String& resource() const
00416 { return m_resource; }
00417
00422 inline bool isFull() const
00423 { return m_node && m_domain && m_resource; }
00424
00431 inline bool match(const JabberID& src) const
00432 { return (src.resource().null() || (resource() == src.resource())) && (bare() &= src.bare()); }
00433
00439 inline bool operator==(const JabberID& src) const
00440 { return (resource() == src.resource()) && (bare() &= src.bare()); }
00441
00447 inline bool operator==(const String& src) const
00448 { JabberID tmp(src); return operator==(tmp); }
00449
00455 inline bool operator!=(const JabberID& src) const
00456 { return !operator==(src); }
00457
00463 inline bool operator!=(const String& src) const
00464 { return !operator==(src); }
00465
00470 inline void resource(const char* res)
00471 { set(m_node.c_str(),m_domain.c_str(),res); }
00472
00477 void set(const char* jid);
00478
00485 void set(const char* node, const char* domain, const char* resource = 0);
00486
00492 static bool valid(const String& value);
00493
00497 static Regexp s_regExpValid;
00498
00499 private:
00500 void parse();
00501
00502 String m_node;
00503 String m_domain;
00504 String m_resource;
00505 String m_bare;
00506 };
00507
00508
00513 class YJINGLE_API JIDIdentity : public RefObject
00514 {
00515 public:
00519 enum Category {
00520 Account,
00521 Client,
00522 Component,
00523 Gateway,
00524 CategoryUnknown
00525 };
00526
00530 enum Type {
00531 AccountRegistered,
00532 ClientPhone,
00533 ComponentGeneric,
00534 ComponentPresence,
00535 GatewayGeneric,
00536 TypeUnknown
00537 };
00538
00545 inline JIDIdentity(Category c, Type t, const char* name = 0)
00546 : m_name(name), m_category(c), m_type(t)
00547 {}
00548
00552 virtual ~JIDIdentity()
00553 {}
00554
00559 XMLElement* toXML();
00560
00565 bool fromXML(const XMLElement* element);
00566
00571 virtual const String& toString() const
00572 { return m_name; }
00573
00579 virtual void* getObject(const String& name) const {
00580 if (name == "JIDIdentity")
00581 return (void*)this;
00582 return RefObject::getObject(name);
00583 }
00584
00589 inline void setName(const char* name)
00590 { if (name) m_name = name; }
00591
00596 static inline const char* categoryText(Category c)
00597 { return lookup(c,s_category); }
00598
00603 static inline Category categoryValue(const char* c)
00604 { return (Category)lookup(c,s_category,CategoryUnknown); }
00605
00610 static inline const char* typeText(Type t)
00611 { return lookup(t,s_type); }
00612
00617 static inline Type typeValue(const char* t)
00618 { return (Type)lookup(t,s_category,TypeUnknown); }
00619
00620 private:
00621 static TokenDict s_category[];
00622 static TokenDict s_type[];
00623
00624 String m_name;
00625 Category m_category;
00626 Type m_type;
00627 };
00628
00629
00634 class YJINGLE_API JIDFeature : public RefObject
00635 {
00636 public:
00642 inline JIDFeature(XMPPNamespace::Type feature, bool required = false)
00643 : m_feature(feature),
00644 m_required(required)
00645 {}
00646
00650 virtual ~JIDFeature()
00651 {}
00652
00657 inline bool required() const
00658 { return m_required; }
00659
00663 inline operator XMPPNamespace::Type()
00664 { return m_feature; }
00665
00666 private:
00667 XMPPNamespace::Type m_feature;
00668 bool m_required;
00669 };
00670
00671
00676 class YJINGLE_API JIDFeatureSasl : public JIDFeature
00677 {
00678 public:
00682 enum Mechanism {
00683 MechNone = 0x00,
00684 MechMD5 = 0x01,
00685 MechSHA1 = 0x02,
00686 MechPlain = 0x04,
00687 };
00688
00694 inline JIDFeatureSasl(int mech, bool required = false)
00695 : JIDFeature(XMPPNamespace::Sasl,required),
00696 m_mechanism(mech)
00697 {}
00698
00703 inline int mechanism() const
00704 { return m_mechanism; }
00705
00710 inline bool mechanism(Mechanism mech) const
00711 { return 0 != (m_mechanism & mech); }
00712
00716 inline operator XMPPNamespace::Type()
00717 { return JIDFeature::operator XMPPNamespace::Type(); }
00718
00722 static TokenDict s_authMech[];
00723
00724 private:
00725 int m_mechanism;
00726 };
00727
00728
00733 class YJINGLE_API JIDFeatureList
00734 {
00735 public:
00742 inline bool add(XMPPNamespace::Type feature, bool required = false) {
00743 if (get(feature))
00744 return false;
00745 m_features.append(new JIDFeature(feature,required));
00746 return true;
00747 }
00748
00754 inline bool add(JIDFeature* feature) {
00755 if (!feature || get(*feature)) {
00756 TelEngine::destruct(feature);
00757 return false;
00758 }
00759 m_features.append(feature);
00760 return true;
00761 }
00762
00767 inline void remove(XMPPNamespace::Type feature)
00768 { m_features.remove(get(feature),true); }
00769
00775 JIDFeature* get(XMPPNamespace::Type feature);
00776
00782 XMLElement* addTo(XMLElement* element);
00783
00790 void fromXml(XMLElement* element, bool reset = true);
00791
00795 inline void clear()
00796 { m_features.clear(); }
00797
00798 private:
00799 ObjList m_features;
00800 };
00801
00802
00807 class YJINGLE_API XMPPUtils
00808 {
00809 public:
00813 enum IqType {
00814 IqSet,
00815 IqGet,
00816 IqResult,
00817 IqError,
00818 IqCount,
00819 };
00820
00824 enum CommandAction {
00825 CommExecute,
00826 CommCancel,
00827 CommPrev,
00828 CommNext,
00829 CommComplete,
00830 };
00831
00835 enum CommandStatus {
00836 CommExecuting,
00837 CommCompleted,
00838 CommCancelled,
00839 };
00840
00848 static XMLElement* createElement(const char* name, XMPPNamespace::Type ns,
00849 const char* text = 0);
00850
00858 static XMLElement* createElement(XMLElement::Type type, XMPPNamespace::Type ns,
00859 const char* text = 0);
00860
00869 static XMLElement* createIq(IqType type, const char* from,
00870 const char* to, const char* id);
00871
00880 static XMLElement* createIqBind(const char* from,
00881 const char* to, const char* id, const ObjList& resources);
00882
00891 static XMLElement* createVCard(bool get, const char* from, const char* to, const char* id);
00892
00900 static XMLElement* createCommand(CommandAction action, const char* node,
00901 const char* sessionId = 0);
00902
00910 static XMLElement* createIdentity(const char* category,
00911 const char* type, const char* name);
00912
00921 static XMLElement* createIqDisco(const char* from, const char* to,
00922 const char* id, bool info = true);
00923
00934 static XMLElement* createDiscoInfoRes(const char* from, const char* to,
00935 const char* id, JIDFeatureList* features, JIDIdentity* identity);
00936
00944 static XMLElement* createError(XMPPError::ErrorType type,
00945 XMPPError::Type error, const char* text = 0);
00946
00956 static XMLElement* createError(XMLElement* xml, XMPPError::ErrorType type,
00957 XMPPError::Type error, const char* text = 0);
00958
00965 static XMLElement* createStreamError(XMPPError::Type error,
00966 const char* text = 0);
00967
00979 static XMLElement* createRegisterQuery(IqType type, const char* from,
00980 const char* to, const char* id,
00981 XMLElement* child1 = 0, XMLElement* child2 = 0, XMLElement* child3 = 0);
00982
00992 static inline XMLElement* createRegisterQuery(const char* from,
00993 const char* to, const char* id,
00994 const char* username, const char* password) {
00995 return createRegisterQuery(XMPPUtils::IqSet,from,to,id,
00996 new XMLElement(XMLElement::Username,0,username),
00997 new XMLElement(XMLElement::Password,0,password));
00998 }
00999
01006 static bool hasXmlns(XMLElement& element, XMPPNamespace::Type ns);
01007
01014 static void decodeError(XMLElement* element, String& error, String& text);
01015
01023 static void encodeDateTimeSec(String& buf, unsigned int timeSec,
01024 unsigned int fractions = 0);
01025
01033 static unsigned int decodeDateTimeSec(const String& time, unsigned int* fractions = 0);
01034
01041 static void print(String& xmlStr, XMLElement& element, const char* indent = 0);
01042
01052 static bool split(NamedList& dest, const char* src, const char sep,
01053 bool nameFirst);
01054
01061 static int decodeFlags(const String& src, const TokenDict* dict);
01062
01069 static void buildFlags(String& dest, int src, const TokenDict* dict);
01070
01077 static bool addChidren(XMLElement* dest, ObjList& list);
01078
01084 static inline IqType iqType(const char* text)
01085 { return (IqType)lookup(text,s_iq,IqCount); }
01086
01090 static TokenDict s_iq[];
01091
01095 static TokenDict s_commandAction[];
01096
01100 static TokenDict s_commandStatus[];
01101 };
01102
01107 class YJINGLE_API XMPPDirVal
01108 {
01109 public:
01110 enum Direction {
01111 None = 0,
01112 To = 1,
01113 From = 2,
01114 Both = 3,
01115 };
01116
01121 inline XMPPDirVal(int flags = None)
01122 : m_value(flags)
01123 {}
01124
01129 inline XMPPDirVal(const char* name)
01130 : m_value(lookup(name,None))
01131 {}
01132
01137 inline void replace(int flag)
01138 { m_value = flag; }
01139
01144 inline void replace(const char* name)
01145 { m_value = lookup(name,None); }
01146
01151 inline void set(int flag)
01152 { m_value |= flag; }
01153
01158 inline void reset(int flag)
01159 { m_value &= ~flag; }
01160
01166 inline bool flag(int mask) const
01167 { return (m_value & mask) != 0; }
01168
01173 inline bool to() const
01174 { return flag(To); }
01175
01180 inline bool from() const
01181 { return flag(From); }
01182
01186 inline operator int()
01187 { return m_value; }
01188
01195 static inline const char* lookup(int flag, const char* defVal = "")
01196 { return TelEngine::lookup(flag,s_names,defVal); }
01197
01204 static inline int lookup(const char* name, int defVal = None)
01205 { return TelEngine::lookup(name,s_names,defVal); }
01206
01210 static TokenDict s_names[];
01211
01212 private:
01213 int m_value;
01214 };
01215
01216 };
01217
01218 #endif
01219
01220