Yate
yatesdp.h
00001 /*
00002  * yatesdp.h
00003  * This file is part of the YATE Project http://YATE.null.ro
00004  *
00005  * SDP media handling
00006  *
00007  * Yet Another Telephony Engine - a fully featured software PBX and IVR
00008  * Copyright (C) 2004-2009 Null Team
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00023  */
00024 
00025 #ifndef __YATESDP_H
00026 #define __YATESDP_H
00027 
00028 #ifndef __cplusplus
00029 #error C++ is required
00030 #endif
00031 
00032 #include <yatemime.h>
00033 #include <yatephone.h>
00034 
00035 #ifdef _WINDOWS
00036 
00037 #ifdef LIBYSDP_EXPORTS
00038 #define YSDP_API __declspec(dllexport)
00039 #else
00040 #ifndef LIBYSDP_STATIC
00041 #define YSDP_API __declspec(dllimport)
00042 #endif
00043 #endif
00044 
00045 #endif /* _WINDOWS */
00046 
00047 #ifndef YSDP_API
00048 #define YSDP_API
00049 #endif
00050 
00054 namespace TelEngine {
00055 
00056 class SDPMedia;
00057 class SDPSession;
00058 class SDPParser;
00059 
00064 class YSDP_API SDPMedia : public NamedList
00065 {
00066 public:
00075     SDPMedia(const char* media, const char* transport, const char* formats,
00076         int rport = -1, int lport = -1);
00077 
00081     virtual ~SDPMedia();
00082 
00087     inline bool isAudio() const
00088         { return m_audio; }
00089 
00094     inline bool isModified() const
00095         { return m_modified; }
00096 
00101     inline void setModified(bool modified = true)
00102         { m_modified = modified; }
00103 
00108     inline const String& suffix() const
00109         { return m_suffix; }
00110 
00115     inline const String& transport() const
00116         { return m_transport; }
00117 
00122     inline const String& id() const
00123         { return m_id; }
00124 
00129     inline const String& format() const
00130         { return m_format; }
00131 
00136     inline const String& formats() const
00137         { return m_formats; }
00138 
00143     inline const String& remotePort() const
00144         { return m_rPort; }
00145 
00150     inline const String& localPort() const
00151         { return m_lPort; }
00152 
00157     inline const String& mappings() const
00158         { return m_mappings; }
00159 
00164     inline void mappings(const char* newMap)
00165         { if (newMap) m_mappings = newMap; }
00166 
00171     inline const String& rfc2833() const
00172         { return m_rfc2833; }
00173 
00179     inline void rfc2833(int payload)
00180         {
00181             if (payload >= 0)
00182                 m_rfc2833 = payload;
00183             else
00184                 m_rfc2833 = String::boolText(false);
00185         }
00186 
00191     inline const String& remoteCrypto() const
00192         { return m_rCrypto; }
00193 
00198     inline const String& localCrypto() const
00199         { return m_lCrypto; }
00200 
00205     inline bool securable() const
00206         { return m_securable; }
00207 
00214     inline bool sameAs(const SDPMedia* other, bool ignorePort = false) const
00215         { return other && (other->formats() == m_formats) &&
00216           (other->transport() == m_transport) &&
00217           ((ignorePort && other->remotePort() && m_rPort) ||
00218            (other->remotePort() == m_rPort)); }
00219 
00224     inline bool localChanged() const
00225         { return m_localChanged; }
00226 
00231     inline void setLocalChanged(bool chg = false)
00232         { m_localChanged = chg; }
00233 
00239     const char* fmtList() const;
00240 
00249     bool update(const char* formats, int rport = -1, int lport = -1, bool force = false);
00250 
00256     void update(const NamedList& msg, bool pickFormat);
00257 
00264     void parameter(const char* name, const char* value, bool append);
00265 
00271     void parameter(NamedString* param, bool append);
00272 
00279     void crypto(const char* desc, bool remote);
00280 
00286     void putMedia(NamedList& msg, bool putPort = true);
00287 
00288 private:
00289     bool m_audio;
00290     bool m_modified;
00291     bool m_securable;
00292     // local rtp data changed flag
00293     bool m_localChanged;
00294     // suffix used for this type
00295     String m_suffix;
00296     // transport protocol
00297     String m_transport;
00298     // list of supported format names
00299     String m_formats;
00300     // format used for sending data
00301     String m_format;
00302     // id of the local media channel
00303     String m_id;
00304     // remote media port
00305     String m_rPort;
00306     // mappings of RTP payloads
00307     String m_mappings;
00308     // local media port
00309     String m_lPort;
00310     // payload for telephone/event
00311     String m_rfc2833;
00312     // remote security descriptor
00313     String m_rCrypto;
00314     // local security descriptor
00315     String m_lCrypto;
00316 };
00317 
00318 
00324 class YSDP_API SDPSession
00325 {
00326 public:
00330     enum {
00331         MediaMissing,
00332         MediaStarted,
00333         MediaMuted
00334     };
00335 
00340     SDPSession(SDPParser* parser);
00341 
00347     SDPSession(SDPParser* parser, NamedList& params);
00348 
00352     virtual ~SDPSession();
00353 
00358     inline const String& getHost() const
00359         { return m_host; }
00360 
00365     inline const String& getRtpAddr() const
00366         { return m_externalAddr ? m_externalAddr : m_rtpLocalAddr; }
00367 
00373     bool setMedia(ObjList* media);
00374 
00381     static void putMedia(NamedList& msg, ObjList* media, bool putPort = true);
00382 
00388     inline void putMedia(NamedList& msg, bool putPort = true)
00389         { putMedia(msg,m_rtpMedia,putPort); }
00390 
00396     SDPMedia* getMedia(const String& name) const
00397         { return m_rtpMedia ? static_cast<SDPMedia*>((*m_rtpMedia)[name]) : 0; }
00398 
00403     void setRfc2833(const String& value);
00404 
00409     inline void setRfc2833(const String* value)
00410         { if (value) setRfc2833(*value); }
00411 
00421     bool dispatchRtp(SDPMedia* media, const char* addr, bool start, bool pick, RefObject* context = 0);
00422 
00431     bool dispatchRtp(const char* addr, bool start, RefObject* context = 0);
00432 
00438     bool startRtp(RefObject* context = 0);
00439 
00445     bool updateSDP(const NamedList& params);
00446 
00452     bool updateRtpSDP(const NamedList& params);
00453 
00460     MimeSdpBody* createSDP(const char* addr, ObjList* mediaList = 0);
00461 
00466     MimeSdpBody* createSDP();
00467 
00475     MimeSdpBody* createPasstroughSDP(NamedList& msg, bool update = true);
00476 
00484     inline MimeSdpBody* createRtpSDP(const char* addr, const NamedList& msg)
00485         { updateSDP(msg); return createRtpSDP(addr,false); }
00486 
00493     inline MimeSdpBody* createRtpSDP(const char* addr, bool start)
00494         { return dispatchRtp(addr,start) ? createSDP(getRtpAddr()) : 0; }
00495 
00502     inline MimeSdpBody* createRtpSDP(bool start)
00503         {
00504             if (m_rtpAddr.null()) {
00505                 m_mediaStatus = MediaMuted;
00506                 return createSDP(0);
00507             }
00508             return createRtpSDP(m_rtpAddr,start);
00509         }
00510 
00516     void updateFormats(const NamedList& msg, bool changeMedia = false);
00517 
00524     bool addSdpParams(NamedList& msg, const MimeBody* body);
00525 
00532     bool addSdpParams(NamedList& msg, const String& rawSdp);
00533 
00543     bool addRtpParams(NamedList& msg, const String& natAddr = String::empty(),
00544         const MimeBody* body = 0, bool force = false);
00545 
00550     virtual void resetSdp(bool all = true);
00551 
00560     virtual Message* buildChanRtp(SDPMedia* media, const char* addr, bool start, RefObject* context);
00561 
00567     virtual Message* buildChanRtp(RefObject* context) = 0;
00568 
00573     bool localRtpChanged() const;
00574 
00579     void setLocalRtpChanged(bool chg = false);
00580 
00589     static ObjList* updateRtpSDP(const NamedList& params, String& rtpAddr,
00590         ObjList* oldList = 0);
00591 
00592 protected:
00598     virtual void mediaChanged(const SDPMedia& media);
00599 
00600     SDPParser* m_parser;
00601     int m_mediaStatus;
00602     bool m_rtpForward;                   // Forward RTP flag
00603     bool m_sdpForward;                   // Forward SDP (only if RTP is forwarded)
00604     String m_externalAddr;               // Our external IP address, possibly outside of a NAT
00605     String m_rtpAddr;                    // Remote RTP address
00606     String m_rtpLocalAddr;               // Local RTP address
00607     ObjList* m_rtpMedia;                 // List of media descriptors
00608     int m_sdpSession;                    // Unique SDP session number
00609     int m_sdpVersion;                    // SDP version number, incremented each time we generate a new SDP
00610     String m_host;
00611     bool m_secure;
00612     int m_rfc2833;                       // Payload of RFC 2833 for remote party
00613 };
00614 
00619 class YSDP_API SDPParser : public DebugEnabler, public Mutex
00620 {
00621     friend class SDPSession;
00622 
00623 public:
00630     inline SDPParser(const char* dbgName, const char* sessName, const char* fmts = "alaw,mulaw")
00631         : Mutex(true,"SDPParser"),
00632           m_rfc2833(101),
00633           m_sdpForward(false), m_secure(false), m_ignorePort(false),
00634           m_sessionName(sessName), m_audioFormats(fmts),
00635           m_codecs(""), m_hacks("")
00636         { debugName(dbgName); }
00637 
00643     inline void getAudioFormats(String& buf)
00644         { Lock lock(this); buf = m_audioFormats; }
00645 
00650     inline int rfc2833() const
00651         { return m_rfc2833; }
00652 
00657     inline bool secure() const
00658         { return m_secure; }
00659 
00664     inline bool sdpForward() const
00665         { return m_sdpForward; }
00666 
00671     inline bool ignorePort() const
00672         { return m_ignorePort; }
00673 
00686     ObjList* parse(const MimeSdpBody& sdp, String& addr, ObjList* oldMedia = 0,
00687         const String& media = String::empty(), bool force = false);
00688 
00701     inline ObjList* parse(const MimeSdpBody* sdp, String& addr, ObjList* oldMedia = 0,
00702         const String& media = String::empty(), bool force = false)
00703         { return sdp ? parse(*sdp,addr,oldMedia,media,force) : 0; }
00704 
00711     void initialize(const NamedList* codecs, const NamedList* hacks, const NamedList* general = 0);
00712 
00716     static const TokenDict s_payloads[];
00717 
00721     static const TokenDict s_rtpmap[];
00722 
00723 private:
00724     int m_rfc2833;                       // RFC 2833 payload offered to remote
00725     bool m_sdpForward;                   // Include raw SDP for forwarding
00726     bool m_secure;                       // Offer SRTP
00727     bool m_ignorePort;                   // Ignore port only changes in SDP
00728     String m_sessionName;
00729     String m_audioFormats;               // Default audio formats to be advertised to remote party
00730     NamedList m_codecs;                  // Codecs configuration list
00731     NamedList m_hacks;                   // Various potentially standard breaking settings
00732 };
00733 
00734 }; // namespace TelEngine
00735 
00736 #endif /* __YATESDP_H */
00737 
00738 /* vi: set ts=8 sw=4 sts=4 noet: */