Yate
|
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: */