Yate
yatejingle.h
00001 
00024 #ifndef __YATEJINGLE_H
00025 #define __YATEJINGLE_H
00026 
00027 #include <yateclass.h>
00028 #include <yatejabber.h>
00029 
00033 namespace TelEngine {
00034 
00035 class JGRtpMedia;                        // A Jingle RTP data payload
00036 class JGCrypto;                          // Content crypto data
00037 class JGRtpMediaList;                    // A list of Jingle RTP data payloads
00038 class JGRtpCandidate;                    // A RTP transport candidate
00039 class JGRtpCandidates;                   // A list of RTP transport candidates
00040 class JGSessionContent;                  // A Jingle session content
00041 class JGStreamHost;                      // A Jingle file transfer stream host
00042 class JGSession;                         // A basic Jingle session
00043 class JGSession0;                        // A session implementing the old jingle protocol
00044 class JGSession1;                        // The version 1 of a jingle session
00045 class JGEvent;                           // An event generated by a Jingle session
00046 class JGEngine;                          // The Jingle engine
00047 class JGSentStanza;                      // Sent stanza timeout info
00048 
00049 
00054 class YJABBER_API JGRtpMedia : public GenObject
00055 {
00056 public:
00068     inline JGRtpMedia(const char* id, const char* name, const char* clockrate,
00069         const char* synonym, const char* channels = 0,
00070         const char* pTime = 0, const char* maxPTime = 0, const char* bitRate = 0)
00071         : m_params("")
00072         { set(id,name,clockrate,synonym,channels,pTime,maxPTime,bitRate); }
00073 
00078     inline JGRtpMedia(XmlElement* xml)
00079         : m_params("")
00080         { fromXml(xml); }
00081 
00085     inline JGRtpMedia(const JGRtpMedia& src)
00086         : m_params("") {
00087             set(src.m_id,src.m_name,src.m_clockrate,src.m_synonym,src.m_channels,
00088                 src.m_pTime,src.m_maxPTime,src.m_bitRate);
00089             m_params = src.m_params;
00090         }
00091 
00103     inline void set(const char* id, const char* name, const char* clockrate,
00104         const char* synonym = 0, const char* channels = 0,
00105         const char* pTime = 0, const char* maxPTime = 0, const char* bitRate = 0) {
00106             m_id = id;
00107             m_name = name;
00108             m_clockrate = clockrate;
00109             m_synonym = synonym;
00110             m_channels = channels;
00111             m_pTime = pTime;
00112             m_maxPTime = maxPTime;
00113             m_bitRate = bitRate;
00114             m_params.clearParams();
00115         }
00116 
00121     virtual const String& toString() const
00122         { return m_id; }
00123 
00128     XmlElement* toXml() const;
00129 
00134     void fromXml(XmlElement* xml);
00135 
00139     String m_id;
00140 
00144     String m_name;
00145 
00149     String m_clockrate;
00150 
00154     String m_synonym;
00155 
00159     String m_channels;
00160 
00164     String m_pTime;
00165 
00169     String m_maxPTime;
00170 
00174     String m_bitRate;
00175 
00179     NamedList m_params;
00180 };
00181 
00187 class YJABBER_API JGCrypto : public String
00188 {
00189 public:
00197     inline JGCrypto(const char* tag = "1", const char* suite = 0,
00198         const char* key = 0, const char* session = 0)
00199         : String(tag),
00200         m_suite(suite), m_keyParams(key), m_sessionParams(session)
00201         {}
00202 
00207     inline JGCrypto(const XmlElement* xml)
00208         { fromXml(xml); }
00209 
00214     XmlElement* toXml() const;
00215 
00220     void fromXml(const XmlElement* xml);
00221 
00228     static XmlElement* buildEncryption(const ObjList& list, bool required);
00229 
00236     static void decodeEncryption(const XmlElement* xml, ObjList& list, bool& required);
00237 
00238     String m_suite;
00239     String m_keyParams;
00240     String m_sessionParams;
00241 };
00242 
00247 class YJABBER_API JGRtpMediaList : public ObjList
00248 {
00249 public:
00253     enum Media {
00254         MediaMissing = -1,
00255         MediaUnknown = 0,
00256         Audio        = 1,
00257     };
00258 
00264     inline JGRtpMediaList(Media m = MediaMissing, bool cryptoRequired = false)
00265         : m_media(m), m_bandwidth(0), m_cryptoRequired(cryptoRequired), m_ready(false),
00266         m_telEvent(101), m_telEventName("telephone-event")
00267         {}
00268 
00272     inline ~JGRtpMediaList()
00273         { TelEngine::destruct(m_bandwidth); }
00274 
00279     inline Media media() const
00280         { return m_media; }
00281  
00292     inline void add(const char* id, const char* name, const char* clockrate,
00293         const char* synonym = 0, const char* channels = 0,
00294         const char* pTime = 0, const char* maxPTime = 0)
00295         { append(new JGRtpMedia(id,name,clockrate,synonym,channels,pTime,maxPTime)); }
00296 
00300     void reset();
00301 
00308     void setMedia(const JGRtpMediaList& src, const String& only = String::empty());
00309 
00315     JGRtpMedia* findMedia(const String& id);
00316 
00322     JGRtpMedia* findSynonym(const String& value) const;
00323 
00328     XmlElement* toXml() const;
00329 
00334     void fromXml(XmlElement* xml);
00335 
00343     bool createList(String& dest, bool synonym, const char* sep = ",");
00344 
00351     void addTelEvent(XmlElement* xml, const char* name = 0) const;
00352 
00356     static const TokenDict s_media[];
00357 
00361     Media m_media;
00362 
00366     String m_ssrc;
00367 
00372     NamedString* m_bandwidth;
00373 
00377     bool m_cryptoRequired;
00378     ObjList m_cryptoLocal;
00379     ObjList m_cryptoRemote;
00380 
00384     bool m_ready;
00385 
00389     int m_telEvent;
00390 
00394     String m_telEventName;
00395 
00399     String m_telEventName2;
00400 };
00401 
00402 
00407 class YJABBER_API JGRtpCandidate : public String
00408 {
00409 public:
00413     inline JGRtpCandidate(const char* id, const char* component = "1",
00414         unsigned int generation = 0, unsigned int net = 0, int prio = 0)
00415         : String(id),
00416         m_port(0), m_component(component), m_generation(generation),
00417         m_network(net), m_priority(prio), m_protocol("udp"), m_type("host")
00418         {}
00419 
00425     inline JGRtpCandidate(XmlElement* xml, const JGRtpCandidates& container)
00426         { fromXml(xml,container); }
00427 
00433     virtual XmlElement* toXml(const JGRtpCandidates& container) const;
00434 
00440     void fromXml(XmlElement* xml, const JGRtpCandidates& container);
00441 
00442     String m_address;
00443     String m_port;
00444     String m_component;                  // Candidate component
00445     String m_generation;                 // Candidate generation
00446     String m_network;                    // NIC card (diagnostic only)
00447     String m_priority;                   // Candidate priority
00448     String m_protocol;                   // The only allowable value is "udp"
00449     String m_type;                       // A Candidate Type as defined in ICE-CORE
00450 };
00451 
00452 
00457 class YJABBER_API JGRtpCandidateP2P : public JGRtpCandidate
00458 {
00459     YCLASS(JGRtpCandidateP2P,JGRtpCandidate)
00460 public:
00464     inline JGRtpCandidateP2P()
00465         : JGRtpCandidate("")
00466         {}
00467 
00473     inline JGRtpCandidateP2P(XmlElement* xml, const JGRtpCandidates& container)
00474         : JGRtpCandidate("")
00475         { fromXml(xml,container); }
00476 
00482     virtual XmlElement* toXml(const JGRtpCandidates& container) const;
00483 
00489     void fromXml(XmlElement* xml, const JGRtpCandidates& container);
00490 
00491     String m_username;
00492     String m_password;
00493 };
00494 
00495 
00500 class YJABBER_API JGRtpCandidates : public ObjList
00501 {
00502 public:
00506     enum Type {
00507         Unknown   = -1,
00508         RtpIceUdp = 1,
00509         RtpRawUdp,
00510         RtpP2P,
00511     };
00512 
00517     inline JGRtpCandidates(Type t = Unknown)
00518         : m_type(t)
00519         {}
00520 
00525     inline const char* typeName() const
00526         { return typeName(m_type); }
00527 
00531     inline void generateIceAuth() {
00532             generateIceToken(m_password,true);
00533             generateIceToken(m_ufrag,false);
00534         }
00535 
00539     inline void generateOldIceAuth() {
00540             generateOldIceToken(m_password);
00541             generateOldIceToken(m_ufrag);
00542         }
00543 
00549     JGRtpCandidate* findByComponent(unsigned int component);
00550 
00557     XmlElement* toXml(bool addCandidates, bool addAuth) const;
00558 
00563     void fromXml(XmlElement* element);
00564 
00572     static void generateIceToken(String& dest, bool pwd, unsigned int max = 0);
00573 
00578     static void generateOldIceToken(String& dest);
00579 
00586     static inline const char* typeName(int t, const char* defVal = "unknown")
00587         { return TelEngine::lookup(t,s_type,defVal); }
00588 
00592     static const TokenDict s_type[];
00593 
00594     Type m_type;
00595     String m_password;
00596     String m_ufrag;
00597 };
00598 
00599 
00606 class YJABBER_API JGSessionContent : public RefObject
00607 {
00608 public:
00612     enum Type {
00613         Unknown             = -1,        // Unknown
00614         UnknownFileTransfer = -2,        // Unknown (unsupported) file transfer content
00615         RtpIceUdp           = 1,         // Audio: RTP ICE-UDP transport
00616         RtpRawUdp,                       // Audio: RTP RAW-UDP transport
00617         RtpP2P,                          // 
00618         FileBSBOffer,                    // File offer: byte stream (SOCKS) transport
00619         FileBSBRequest,                  // File request: byte stream (SOCKS) transport
00620     };
00621 
00625     enum Senders {
00626         SendUnknown    = 0,
00627         SendBoth       = 1,
00628         SendInitiator  = 2,
00629         SendResponder  = 3
00630     };
00631 
00635     enum Creator {
00636         CreatorUnknown   = 0,
00637         CreatorInitiator = 1,
00638         CreatorResponder = 2
00639     };
00640 
00649     JGSessionContent(Type t, const char* name, Senders senders,
00650         Creator creator, const char* disposition = 0);
00651 
00656     inline Type type() const
00657         { return m_type; }
00658 
00663     inline Senders senders() const
00664         { return m_senders; }
00665 
00670     inline Creator creator() const
00671         { return m_creator; }
00672 
00678     inline bool isValidAudio() const
00679         { return (m_rtpMedia.media() == JGRtpMediaList::Audio) && (0 != m_rtpMedia.skipNull()); }
00680 
00684     virtual const String& toString() const
00685         { return m_name; }
00686 
00692     inline bool isSession() const
00693         { return !m_disposition || m_disposition == "session"; }
00694 
00699     inline bool isEarlyMedia() const
00700         { return m_disposition == "early-session"; }
00701 
00705     inline void setEarlyMedia()
00706         { m_disposition = "early-session"; }
00707 
00717     XmlElement* toXml(bool minimum, bool addDesc,
00718         bool addTrans, bool addCandidates, bool addAuth) const;
00719 
00727     static JGSessionContent* fromXml(XmlElement* xml, XMPPError::Type& err,
00728         String& error);
00729 
00733     static const TokenDict s_senders[];
00734 
00738     static const TokenDict s_creator[];
00739 
00743     JGRtpMediaList m_rtpMedia;
00744 
00748     JGRtpCandidates m_rtpLocalCandidates;
00749 
00753     JGRtpCandidates m_rtpRemoteCandidates;
00754 
00758     NamedList m_fileTransfer;
00759 
00760 private:
00761     Type m_type;
00762     String m_name;
00763     Senders m_senders;
00764     Creator m_creator;
00765     String m_disposition;
00766 };
00767 
00768 
00773 class JGStreamHost : public String
00774 {
00775 public:
00783     JGStreamHost(const char* jid, const char* addr, int port, const char* zeroConf = 0)
00784         : String(jid),
00785         m_address(addr), m_port(port), m_zeroConf(zeroConf)
00786         {}
00787 
00792     inline JGStreamHost(const JGStreamHost& src)
00793         : String(src),
00794         m_address(src.m_address), m_port(src.m_port),
00795         m_zeroConf(src.m_zeroConf)
00796         {}
00797 
00802     XmlElement* toXml();
00803 
00809     static JGStreamHost* fromXml(XmlElement* xml);
00810 
00818     static XmlElement* buildHosts(const ObjList& hosts, const char* sid,
00819         const char* mode = "tcp");
00820 
00826     static XmlElement* buildRsp(const char* jid);
00827 
00828     String m_address;
00829     int m_port;
00830     String m_zeroConf;
00831 };
00832 
00833 
00838 class YJABBER_API JGSession : public RefObject, public Mutex
00839 {
00840     friend class JGEvent;
00841     friend class JGEngine;
00842 public:
00846     enum Version {
00847         Version0 = 0,
00848         Version1 = 1,
00849         VersionUnknown
00850     };
00851 
00855     enum Reason {
00856         ReasonUnknown = 0,
00857         // Session termination reason
00858         ReasonOk,                        // success
00859         ReasonBusy,                      // busy
00860         ReasonDecline,                   // decline
00861         ReasonCancel,                    // cancel
00862         ReasonExpired,                   // expired
00863         ReasonConn,                      // connectivity-error
00864         ReasonFailApp,                   // failed-application
00865         ReasonFailTransport,             // failed-transport
00866         ReasonGone,                      // gone
00867         ReasonParams,                    // incompatible-parameters
00868         ReasonMedia,                     // media-error
00869         ReasonTransport,                 // unsupported-transports
00870         ReasonApp,                       // unsupported-applications
00871         ReasonSecurity,                  // security-error
00872         ReasonTimeout,                   // timeout
00873         ReasonGeneral,                   // general-error
00874         ReasonAltSess,                   // alternative-session
00875         // Session transfer (XEP 0251)
00876         Transferred,                     // transferred
00877         // RTP session errors (XEP 0167)
00878         CryptoRequired,                  // crypto-required
00879         InvalidCrypto,                   // invalid-crypto
00880     };
00881 
00885     enum RtpInfo {
00886         RtpActive,                       // active
00887         RtpHold,                         // hold
00888         RtpMute,                         // mute
00889         RtpRinging,                      // ringing
00890     };
00891 
00895     enum State {
00896         Idle    = 0,                     // Outgoing stream is waiting for 
00897         Pending = 1,                     // Session is pending, session-initiate sent/received
00898         Active  = 2,                     // Session is active, session-accept sent/received
00899         Ending  = 3,                     // Session terminated: Wait for write result
00900         Destroy = 4,                     // The session will be destroyed
00901     };
00902 
00906     enum Action {
00907         ActAccept,                       // session-accept
00908         ActInitiate,                     // session-initiate
00909         ActTerminate,                    // session-terminate
00910         ActReject,                       // reject
00911         ActInfo,                         // session-info
00912         ActTransportInfo,                // transport-info
00913         ActTransportAccept,              // transport-accept
00914         ActTransportReject,              // transport-reject
00915         ActTransportReplace,             // transport-replace
00916         ActCandidates,                   // candidates
00917         ActContentAccept,                // content-accept
00918         ActContentAdd,                   // content-add
00919         ActContentModify,                // content-modify
00920         ActContentReject,                // content-reject
00921         ActContentRemove,                // content-remove
00922         ActContentInfo,                  // content-info
00923         ActDescriptionInfo,              // description-info
00924         ActTransfer,                     // session-info: Transfer
00925         ActRinging,                      // session-info: Ringing
00926         ActTrying,                       // session-info: Trying
00927         ActReceived,                     // session-info: Received
00928         ActHold,                         // session-info: Hold
00929         ActActive,                       // session-info: Active
00930         ActMute,                         // session-info: Mute
00931         ActDtmf,                         // session-info: Dtmf
00932         ActStreamHost,
00933         ActCount,
00934     };
00935 
00939     enum SessionFlag {
00940         FlagNoPing = 0x0001,             // Don't send ping
00941     };
00942 
00946     virtual ~JGSession();
00947 
00952     inline Version version() const
00953         { return m_version; }
00954 
00959     inline JGEngine* engine() const
00960         { return m_engine; }
00961 
00966     inline bool outgoing() const
00967         { return m_outgoing; }
00968 
00973     inline const String& sid() const
00974         { return m_sid; }
00975 
00980     inline const JabberID& local() const
00981         { return m_local; }
00982 
00987     inline const JabberID& remote() const
00988         { return m_remote; }
00989 
00994     inline State state() const
00995         { return m_state; }
00996 
01002     inline int flag(int mask) const
01003         { return m_flags & mask; }
01004 
01009     inline void setFlags(int value)
01010         { m_flags = value; }
01011 
01016     inline void* userData()
01017         { return m_private; }
01018 
01023     inline void userData(void* userdata)
01024         { m_private = userdata; }
01025 
01030     inline const String& line() const
01031         { return m_line; }
01032 
01037     inline void line(const String& acc)
01038         { m_line = acc; }
01039 
01045     Action getAction(XmlElement* xml);
01046 
01056     bool acceptIq(XMPPUtils::IqType type, const JabberID& from, const JabberID& to,
01057         const String& id, XmlElement* xml);
01058 
01064     bool confirmResult(XmlElement* xml);
01065 
01074     bool confirmError(XmlElement*& xml, XMPPError::Type error,
01075         const char* text = 0, XMPPError::ErrorType type = XMPPError::TypeModify);
01076 
01084     virtual bool accept(const ObjList& contents, String* stanzaId = 0)
01085         { return false; }
01086 
01093     virtual bool hangup(XmlElement* reason = 0);
01094 
01100     virtual XmlElement* createRtpInfoXml(RtpInfo info)
01101         { return 0; }
01102 
01110     virtual XmlElement* createReason(int reason, const char* text = 0,
01111         XmlElement* child = 0)
01112         { return 0; }
01113 
01119     virtual XmlElement* createTransferReason(int reason)
01120         { return 0; }
01121 
01127     virtual XmlElement* createRtpSessionReason(int reason)
01128         { return 0; }
01129 
01139     virtual bool sendContent(Action action, const ObjList& contents, String* stanzaId = 0)
01140         { return false; }
01141 
01151     inline bool sendContent(Action action, const JGSessionContent* content,
01152         String* stanzaId = 0) {
01153             if (!content)
01154                 return false;
01155             ObjList tmp;
01156             tmp.append(content)->setDelete(false);
01157             return sendContent(action,tmp,stanzaId);
01158         }
01159 
01168     virtual bool sendStreamHosts(const ObjList& hosts, String* stanzaId = 0)
01169         { return false; }
01170 
01179     virtual bool sendStreamHostUsed(const char* jid, const char* stanzaId)
01180         { return false; }
01181 
01186     void buildSocksDstAddr(String& buf);
01187 
01195     bool sendInfo(XmlElement* xml, String* stanzaId = 0);
01196 
01205     bool sendDtmf(const char* dtmf, unsigned int msDuration = 0, String* stanzaId = 0);
01206 
01212     bool hasFeature(XMPPNamespace::Type feature);
01213 
01221     static XmlElement* buildTransfer(const String& transferTo, const String& transferFrom,
01222         const String& sid = String::empty());
01223 
01230     static inline Version lookupVersion(const char* value, Version def = VersionUnknown)
01231         { return (Version)lookup(value,s_versions,def); }
01232 
01239     static inline const char* lookupVersion(int value, const char* def = "unknown")
01240         { return lookup(value,s_versions,def); }
01241 
01248     static inline int lookupReason(const char* value, int def = ReasonOk)
01249         { return lookup(value,s_reasons,def); }
01250 
01257     static inline const char* lookupReason(int value, const char* def = 0)
01258         { return lookup(value,s_reasons,def); }
01259 
01265     static const char* lookupState(int state)
01266         { return lookup(state,s_states); }
01267 
01274     static const char* lookupAction(int act, Version ver);
01275 
01282     static Action lookupAction(const char* str, Version ver);
01283 
01287     static const TokenDict s_versions[];
01288 
01292     static const TokenDict s_reasons[];
01293 
01297     static const TokenDict s_rtpInfo[];
01298 
01302     static const TokenDict s_states[];
01303 
01307     static const TokenDict s_actions0[];
01308 
01312     static const TokenDict s_actions1[];
01313 
01317     static const TokenDict s_flagName[];
01318 
01319 protected:
01327     JGSession(Version ver, JGEngine* engine,
01328         const JabberID& caller, const JabberID& called);
01329 
01339     JGSession(Version ver, JGEngine* engine, const JabberID& caller,
01340         const JabberID& called, XmlElement* xml, const String& id);
01341 
01349     virtual bool initiate(const ObjList& contents, XmlElement* extra,
01350         const char* subject = 0) = 0;
01351 
01358     virtual JGEvent* getEvent(u_int64_t time);
01359 
01363     virtual void destroyed();
01364 
01373     bool sendStanza(XmlElement* stanza, String* stanzaId = 0, bool confirmation = true,
01374         bool ping = false);
01375 
01381     bool sendPing(u_int64_t msecNow);
01382 
01389     virtual JGEvent* decodeJingle(XmlElement*& xml, XmlElement* child) = 0;
01390 
01399     virtual XmlElement* createJingle(Action action, XmlElement* element1 = 0,
01400         XmlElement* element2 = 0, XmlElement* element3 = 0) = 0;
01401 
01408     virtual XmlElement* createDtmf(const char* dtmf, unsigned int msDuration = 0) = 0;
01409 
01416     virtual JGEvent* processJingleSetEvent(JGEvent*& ev);
01417 
01424     virtual JGEvent* processJabberIqResponse(bool result, XmlElement*& xml);
01425 
01433     virtual JGEvent* processFileTransfer(bool set, XmlElement*& xml, XmlElement* child);
01434 
01439     void eventTerminated(JGEvent* event);
01440 
01445     void changeState(State newState);
01446 
01447     Version m_version;                   // Session version
01448     State m_state;                       // Session state
01449     int m_flags;                         // Session flags
01450     u_int64_t m_timeToPing;              // Time to send ping (empty session-info)
01451     JGEngine* m_engine;                  // The engine that owns this session
01452     bool m_outgoing;                     // Session direction
01453     String m_sid;                        // Session id
01454     JabberID m_local;                    // Local peer's JID
01455     JabberID m_remote;                   // Remote peer's JID
01456     XmlFragment m_queue;                 // Incoming, unprocessed, xml elements
01457     JGEvent* m_lastEvent;                // Last generated event
01458     bool m_recvTerminate;                // Flag indicating whether session-terminate was received
01459     void* m_private;                     // Arbitrary user data
01460     String m_localSid;                   // Local session id (used to generate element's id)
01461     u_int32_t m_stanzaId;                // Sent stanza id counter
01462     ObjList m_sentStanza;                // Sent stanzas' id
01463     String m_line;                       // Session account
01464 
01465 private:
01466     JGSession() {}                       // Don't use it
01467 };
01468 
01469 
01474 class YJABBER_API JGSession0 : public JGSession
01475 {
01476     friend class JGEvent;
01477     friend class JGEngine;
01478 public:
01482     virtual ~JGSession0();
01483 
01491     virtual bool accept(const ObjList& contents, String* stanzaId = 0);
01492 
01493 protected:
01500     JGSession0(JGEngine* engine, const JabberID& caller, const JabberID& called);
01501 
01510     JGSession0(JGEngine* engine, const JabberID& caller, const JabberID& called,
01511         XmlElement* xml, const String& id);
01512 
01520     virtual bool initiate(const ObjList& contents, XmlElement* extra,
01521         const char* subject = 0);
01522 
01532     virtual bool sendContent(Action action, const ObjList& contents, String* stanzaId = 0);
01533 
01540     virtual JGEvent* decodeJingle(XmlElement*& xml, XmlElement* child);
01541 
01550     virtual XmlElement* createJingle(Action action, XmlElement* element1 = 0,
01551         XmlElement* element2 = 0, XmlElement* element3 = 0);
01552 
01559     virtual XmlElement* createDtmf(const char* dtmf, unsigned int msDuration = 0);
01560 
01561 protected:
01562     String m_sessContentName;            // Content name advertised to upper layer
01563     Action m_candidatesAction;           // Use candidates/transport-info for candidates
01564 };
01565 
01570 class YJABBER_API JGSession1 : public JGSession
01571 {
01572     friend class JGEvent;
01573     friend class JGEngine;
01574 public:
01578     virtual ~JGSession1();
01579 
01587     virtual bool accept(const ObjList& contents, String* stanzaId = 0);
01588 
01594     virtual XmlElement* createRtpInfoXml(RtpInfo info);
01595 
01603     virtual XmlElement* createReason(int reason, const char* text = 0,
01604         XmlElement* child = 0);
01605 
01611     virtual XmlElement* createTransferReason(int reason);
01612 
01618     virtual XmlElement* createRtpSessionReason(int reason);
01619 
01629     virtual bool sendContent(Action action, const ObjList& contents, String* stanzaId = 0);
01630 
01639     virtual bool sendStreamHosts(const ObjList& hosts, String* stanzaId = 0);
01640 
01649     virtual bool sendStreamHostUsed(const char* jid, const char* stanzaId);
01650 
01651 protected:
01658     JGSession1(JGEngine* engine, const JabberID& caller, const JabberID& called);
01659 
01668     JGSession1(JGEngine* engine, const JabberID& caller, const JabberID& called,
01669         XmlElement* xml, const String& id);
01670 
01678     virtual bool initiate(const ObjList& contents, XmlElement* extra,
01679         const char* subject = 0);
01680 
01687     virtual JGEvent* decodeJingle(XmlElement*& xml, XmlElement* child);
01688 
01697     virtual XmlElement* createJingle(Action action, XmlElement* element1 = 0,
01698         XmlElement* element2 = 0, XmlElement* element3 = 0);
01699 
01706     virtual XmlElement* createDtmf(const char* dtmf, unsigned int msDuration = 0);
01707 
01715     virtual JGEvent* processFileTransfer(bool set, XmlElement*& xml, XmlElement* child);
01716 
01717 };
01718 
01723 class YJABBER_API JGEvent
01724 {
01725     friend class JGSession;
01726     friend class JGSession0;
01727     friend class JGSession1;
01728 public:
01732     enum Type {
01733         Jingle,                          //
01734         ResultOk,                        // Response for a sent stanza (iq with type=result)
01735         ResultError,                     // Response for a sent stanza (iq with type=error)
01736         ResultTimeout,                   // Response for a sent stanza (stanza timeout)
01737         // Final
01738         Terminated,                      // m_element is the element that caused the termination
01739                                          //  m_reason contains the reason
01740         Destroy,                         // The engine sould delete the event (causing session destruction)
01741     };
01742 
01746     virtual ~JGEvent();
01747 
01752     inline Type type() const
01753         { return m_type; }
01754 
01759     inline const char* name()
01760         { return lookupType(m_type); }
01761 
01766     inline JGSession* session() const
01767         { return m_session; }
01768 
01773     inline XmlElement* element() const
01774         { return m_element; }
01775 
01781     inline XmlElement* jingle() const
01782         { return m_jingle; }
01783 
01788     inline JGSession::Action action() const
01789         { return m_action; }
01790 
01795     inline const char* actionName() const
01796         { return m_session ? JGSession::lookupAction(m_action,m_session->version()) : ""; }
01797 
01802     inline const String& id() const
01803         { return m_id; }
01804 
01809     inline const String& reason() const
01810         { return m_reason; }
01811 
01816     inline const String& text() const
01817         { return m_text; }
01818 
01823     inline XmlElement* releaseXml() {
01824             XmlElement* tmp = m_element;
01825             m_jingle = m_element = 0;
01826             return tmp;
01827          }
01828 
01833     inline bool final() const
01834         { return m_type == Terminated || m_type == Destroy; }
01835 
01843     inline bool confirmElement(XMPPError::Type error = XMPPError::NoError,
01844         const char* text = 0, XMPPError::ErrorType type = XMPPError::TypeModify) {
01845             if (m_session && element() && !m_confirmed) {
01846                 m_confirmed = true;
01847                 if (error == XMPPError::NoError)
01848                     return m_session->confirmResult(element());
01849                 XmlElement* err = releaseXml();
01850                 return m_session->confirmError(err,error,text,type);
01851             }
01852             return false;
01853         }
01854 
01858     inline void setConfirmed()
01859         { m_confirmed = true; }
01860 
01866     void setAction(JGSession::Action act);
01867 
01872     static inline const char* lookupType(int type)
01873         { return lookup(type,s_typeName); }
01874 
01878     static const TokenDict s_typeName[];
01879 
01883     ObjList m_contents;
01884 
01888     ObjList m_streamHosts;
01889 
01890 protected:
01899     inline JGEvent(Type type, JGSession* session, XmlElement* element = 0,
01900         const char* reason = 0, const char* text = 0)
01901         : m_type(type), m_confirmed(true), m_session(0), m_element(element),
01902         m_jingle(0), m_action(JGSession::ActCount), m_reason(reason), m_text(text)
01903         { init(session); }
01904 
01913     inline JGEvent(JGSession::Action act, JGSession* session, XmlElement* element,
01914         const char* reason = 0, const char* text = 0)
01915         : m_type(Jingle), m_confirmed(false), m_session(0), m_element(element), m_jingle(0),
01916         m_action(act), m_reason(reason), m_text(text) {
01917             init(session);
01918             setAction(act);
01919         }
01920 
01921 private:
01922     JGEvent() {}                         // Don't use it
01923     void init(JGSession* session);
01924 
01925     Type m_type;                         // The type of this event
01926     bool m_confirmed;                    // Flag indicating that element was confirmed
01927     JGSession* m_session;                // Jingle session that generated this event
01928     XmlElement* m_element;               // XML element that generated this event
01929     XmlElement* m_jingle;                // The session child, if present
01930     // Event specific
01931     JGSession::Action m_action;          // The action if type is Jingle
01932     String m_id;                         // The element's id attribute
01933     String m_reason;                     // The reason if type is Error or Terminated 
01934     String m_text;                       // Dtmf text
01935 };
01936 
01942 class YJABBER_API JGEngine : public DebugEnabler, public Mutex
01943 {
01944     friend class JGSession;
01945 public:
01950     JGEngine(const char* name = "jgengine");
01951 
01955     virtual ~JGEngine();
01956 
01961     inline int sessionFlags() const
01962         { return m_sessionFlags; }
01963 
01968     inline u_int64_t stanzaTimeout() const
01969         { return m_stanzaTimeout; }
01970 
01975     inline u_int64_t pingInterval() const
01976         { return m_pingInterval; }
01977 
01982     virtual void initialize(const NamedList& params);
01983 
01991     virtual bool sendStanza(JGSession* session, XmlElement*& stanza);
01992 
01999     virtual bool sendMessage(JGSession* session, const char* body);
02000 
02007     JGEvent* getEvent(u_int64_t time);
02008 
02023     JGSession* call(JGSession::Version ver, const JabberID& caller, const JabberID& called,
02024         const ObjList& contents, XmlElement* extra = 0, const char* msg = 0,
02025         const char* subject = 0, const char* line = 0, int* flags = 0);
02026 
02040     bool acceptIq(XMPPUtils::IqType type, const JabberID& from, const JabberID& to,
02041         const String& id, XmlElement* xml, const char* line,
02042         XMPPError::Type& error, String& text);
02043 
02048     void defProcessEvent(JGEvent* event);
02049 
02055     virtual void processEvent(JGEvent* event);
02056 
02063     static int decodeFlags(const String& list, const TokenDict* dict);
02064 
02071     static void encodeFlags(String& buf, int flags, const TokenDict* dict);
02072 
02073 private:
02074     // Create a local session id
02075     void createSessionId(String& id);
02076 
02077     ObjList m_sessions;                  // List of sessions
02078     u_int32_t m_sessionId;               // Session id counter
02079     u_int64_t m_stanzaTimeout;           // The timeout of a sent stanza
02080     u_int64_t m_pingInterval;            // Interval to send ping (empty session-info)
02081     int m_sessionFlags;                  // Default session flags
02082 };
02083 
02084 
02089 class YJABBER_API JGSentStanza : public String
02090 {
02091 public:
02099     JGSentStanza(const char* id, u_int64_t time, bool notif = false, bool ping = false)
02100         : String(id), m_time(time), m_notify(notif), m_ping(ping)
02101         {}
02102 
02107     inline bool timeout(u_int64_t time) const
02108         { return time > m_time; }
02109 
02114     inline bool notify() const
02115         { return m_notify; }
02116 
02121     inline bool ping() const
02122         { return m_ping; }
02123 
02124 private:
02125     u_int64_t m_time;                    // Timeout
02126     bool m_notify;                       // Notify timeout to sender
02127     bool m_ping;                         // Sent stanza is a ping one
02128 };
02129 
02130 };
02131 
02132 #endif /* __YATEJINGLE_H */
02133 
02134 /* vi: set ts=8 sw=4 sts=4 noet: */