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 
00248     bool update(const char* formats, int rport = -1, int lport = -1);
00249 
00255     void update(const NamedList& msg, bool pickFormat);
00256 
00263     void parameter(const char* name, const char* value, bool append);
00264 
00270     void parameter(NamedString* param, bool append);
00271 
00278     void crypto(const char* desc, bool remote);
00279 
00285     void putMedia(NamedList& msg, bool putPort = true);
00286 
00287 private:
00288     bool m_audio;
00289     bool m_modified;
00290     bool m_securable;
00291     // local rtp data changed flag
00292     bool m_localChanged;
00293     // suffix used for this type
00294     String m_suffix;
00295     // transport protocol
00296     String m_transport;
00297     // list of supported format names
00298     String m_formats;
00299     // format used for sending data
00300     String m_format;
00301     // id of the local media channel
00302     String m_id;
00303     // remote media port
00304     String m_rPort;
00305     // mappings of RTP payloads
00306     String m_mappings;
00307     // local media port
00308     String m_lPort;
00309     // payload for telephone/event
00310     String m_rfc2833;
00311     // remote security descriptor
00312     String m_rCrypto;
00313     // local security descriptor
00314     String m_lCrypto;
00315 };
00316 
00317 
00323 class YSDP_API SDPSession
00324 {
00325 public:
00329     enum {
00330         MediaMissing,
00331         MediaStarted,
00332         MediaMuted
00333     };
00334 
00339     SDPSession(SDPParser* parser);
00340 
00346     SDPSession(SDPParser* parser, NamedList& params);
00347 
00351     virtual ~SDPSession();
00352 
00357     inline const String& getHost() const
00358         { return m_host; }
00359 
00364     inline const String& getRtpAddr() const
00365         { return m_externalAddr ? m_externalAddr : m_rtpLocalAddr; }
00366 
00372     bool setMedia(ObjList* media);
00373 
00380     static void putMedia(NamedList& msg, ObjList* media, bool putPort = true);
00381 
00387     inline void putMedia(NamedList& msg, bool putPort = true)
00388         { putMedia(msg,m_rtpMedia,putPort); }
00389 
00399     bool dispatchRtp(SDPMedia* media, const char* addr, bool start, bool pick, RefObject* context = 0);
00400 
00409     bool dispatchRtp(const char* addr, bool start, RefObject* context = 0);
00410 
00416     bool startRtp(RefObject* context = 0);
00417 
00423     bool updateSDP(const NamedList& params);
00424 
00430     bool updateRtpSDP(const NamedList& params);
00431 
00438     MimeSdpBody* createSDP(const char* addr, ObjList* mediaList = 0);
00439 
00444     MimeSdpBody* createSDP();
00445 
00453     MimeSdpBody* createPasstroughSDP(NamedList& msg, bool update = true);
00454 
00462     inline MimeSdpBody* createRtpSDP(const char* addr, const NamedList& msg)
00463         { updateSDP(msg); return createRtpSDP(addr,false); }
00464 
00471     inline MimeSdpBody* createRtpSDP(const char* addr, bool start)
00472         { return dispatchRtp(addr,start) ? createSDP(getRtpAddr()) : 0; }
00473 
00480     inline MimeSdpBody* createRtpSDP(bool start)
00481         {
00482             if (m_rtpAddr.null()) {
00483                 m_mediaStatus = MediaMuted;
00484                 return createSDP(0);
00485             }
00486             return createRtpSDP(m_rtpAddr,start);
00487         }
00488 
00494     void updateFormats(const NamedList& msg, bool changeMedia = false);
00495 
00502     bool addSdpParams(NamedList& msg, const MimeBody* body);
00503 
00510     bool addSdpParams(NamedList& msg, const String& rawSdp);
00511 
00521     bool addRtpParams(NamedList& msg, const String& natAddr = String::empty(),
00522         const MimeBody* body = 0, bool force = false);
00523 
00527     virtual void resetSdp();
00528 
00537     virtual Message* buildChanRtp(SDPMedia* media, const char* addr, bool start, RefObject* context);
00538 
00544     virtual Message* buildChanRtp(RefObject* context) = 0;
00545 
00550     bool localRtpChanged() const;
00551 
00556     void setLocalRtpChanged(bool chg = false);
00557 
00566     static ObjList* updateRtpSDP(const NamedList& params, String& rtpAddr,
00567         ObjList* oldList = 0);
00568 
00569     SDPParser* m_parser;
00570     int m_mediaStatus;
00571     bool m_rtpForward;                   // Forward RTP flag
00572     bool m_sdpForward;                   // Forward SDP (only if RTP is forwarded)
00573     String m_externalAddr;               // Our external IP address, possibly outside of a NAT
00574     String m_rtpAddr;                    // Remote RTP address
00575     String m_rtpLocalAddr;               // Local RTP address
00576     ObjList* m_rtpMedia;                 // List of media descriptors
00577     int m_sdpSession;                    // Unique SDP session number
00578     int m_sdpVersion;                    // SDP version number, incremented each time we generate a new SDP
00579     String m_host;
00580     bool m_secure;
00581     bool m_rfc2833;                      // Offer RFC 2833 to remote party
00582 
00583 protected:
00589     virtual void mediaChanged(const SDPMedia& media);
00590 };
00591 
00596 class YSDP_API SDPParser : public DebugEnabler, public Mutex
00597 {
00598     friend class SDPSession;
00599 
00600 public:
00607     inline SDPParser(const char* dbgName, const char* sessName, const char* fmts = "alaw,mulaw")
00608         : Mutex(true,"SDPParser"), m_sdpForward(false),
00609           m_rfc2833(true), m_secure(false), m_ignorePort(false),
00610           m_sessionName(sessName), m_audioFormats(fmts),
00611           m_codecs(""), m_hacks("")
00612         { debugName(dbgName); }
00613 
00619     inline void getAudioFormats(String& buf)
00620         { Lock lock(this); buf = m_audioFormats; }
00621 
00626     inline bool rfc2833() const
00627         { return m_rfc2833; }
00628 
00633     inline bool secure() const
00634         { return m_secure; }
00635 
00640     inline bool sdpForward() const
00641         { return m_sdpForward; }
00642 
00647     inline bool ignorePort() const
00648         { return m_ignorePort; }
00649 
00661     ObjList* parse(const MimeSdpBody& sdp, String& addr, ObjList* oldMedia = 0,
00662         const String& media = String::empty());
00663 
00675     inline ObjList* parse(const MimeSdpBody* sdp, String& addr, ObjList* oldMedia = 0,
00676         const String& media = String::empty())
00677         { return sdp ? parse(*sdp,addr,oldMedia,media) : 0; }
00678 
00685     void initialize(const NamedList* codecs, const NamedList* hacks, const NamedList* general = 0);
00686 
00690     static const TokenDict s_payloads[];
00691 
00695     static const TokenDict s_rtpmap[];
00696 
00697 private:
00698     bool m_sdpForward;                   // Include raw SDP for forwarding
00699     bool m_rfc2833;                      // Offer RFC 2833 to remote party
00700     bool m_secure;                       // Offer SRTP
00701     bool m_ignorePort;                   // Ignore port only changes in SDP
00702     String m_sessionName;
00703     String m_audioFormats;               // Default audio formats to be advertised to remote party
00704     NamedList m_codecs;                  // Codecs configuration list
00705     NamedList m_hacks;                   // Various potentially standard breaking settings
00706 };
00707 
00708 }; // namespace TelEngine
00709 
00710 #endif /* __YATESDP_H */
00711 
00712 /* vi: set ts=8 sw=4 sts=4 noet: */