OPAL
Version 3.10.4
|
00001 /* 00002 * msrp.h 00003 * 00004 * Support for RFC 4975 Message Session Relay Protocol (MSRP) 00005 * 00006 * Open Phone Abstraction Library (OPAL) 00007 * 00008 * Copyright (c) 2008 Post Increment 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Open Phone Abstraction Library. 00021 * 00022 * The Initial Developer of the Original Code is Post Increment 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Revision: 23593 $ 00027 * $Author: csoutheren $ 00028 * $Date: 2009-10-06 01:23:00 -0500 (Tue, 06 Oct 2009) $ 00029 */ 00030 00031 #ifndef OPAL_IM_MSRP_H 00032 #define OPAL_IM_MSRP_H 00033 00034 #include <ptlib.h> 00035 #include <opal/buildopts.h> 00036 #include <opal/rtpconn.h> 00037 #include <opal/manager.h> 00038 #include <opal/mediastrm.h> 00039 #include <opal/mediatype.h> 00040 #include <im/im.h> 00041 #include <ptclib/inetprot.h> 00042 #include <ptclib/guid.h> 00043 #include <ptclib/mime.h> 00044 00045 #if OPAL_SIP 00046 #include <sip/sdp.h> 00047 #endif 00048 00049 #if OPAL_HAS_MSRP 00050 00051 class OpalMSRPMediaType : public OpalIMMediaType 00052 { 00053 public: 00054 OpalMSRPMediaType(); 00055 virtual OpalMediaSession * CreateMediaSession(OpalConnection & conn, unsigned sessionID) const; 00056 00057 #if OPAL_SIP 00058 SDPMediaDescription * CreateSDPMediaDescription(const OpalTransportAddress & localAddress); 00059 #endif 00060 }; 00061 00062 00064 // 00065 // Ancestor for all MSRP encoding types 00066 // 00067 00068 class OpalMSRPEncoding { 00069 }; 00070 00071 00073 // 00074 // Ancestor for MSRP protocol 00075 // 00076 00077 class MSRPProtocol : public PInternetProtocol 00078 { 00079 public: 00080 enum Commands { 00081 SEND, 00082 REPORT, 00083 NumCommands 00084 }; 00085 00086 static const unsigned MaximumMessageLength = 1024; 00087 00088 class Message 00089 { 00090 public: 00091 struct Chunk { 00092 Chunk(const PString & id, unsigned from, unsigned len) 00093 : m_chunkId(id), m_rangeFrom(from + 1), m_rangeTo(from + len) { } 00094 00095 PString m_chunkId; 00096 unsigned m_rangeFrom; 00097 unsigned m_rangeTo; 00098 }; 00099 typedef std::vector<Chunk> ChunkList; 00100 ChunkList m_chunks; 00101 00102 PString m_id; 00103 PURL m_fromURL; 00104 PURL m_toURL; 00105 PString m_contentType; 00106 unsigned m_length; 00107 }; 00108 00109 MSRPProtocol(); 00110 00111 bool SendSEND( 00112 const PURL & from, 00113 const PURL & to, 00114 const PString & text, 00115 const PString & contentType, 00116 PString & messageId 00117 ); 00118 00119 bool SendChunk( 00120 const PString & transactionId, 00121 const PString toUrl, 00122 const PString fromUrl, 00123 const PMIMEInfo & mime, 00124 const PString & body 00125 ); 00126 00127 bool SendResponse(const PString & chunkId, 00128 unsigned response, 00129 const PString & text, 00130 const PString & toUrl, 00131 const PString & fromUrl); 00132 00133 bool SendREPORT(const PString & chunkId, 00134 const PString & toUrl, 00135 const PString & fromUrl, 00136 const PMIMEInfo & mime); 00137 00138 bool ReadMessage( 00139 int & command, 00140 PString & chunkId, 00141 PMIMEInfo & mime, 00142 PString & body 00143 ); 00144 00145 //typedef std::map<std::string, Message> MessageMap; 00146 //MessageMap m_messageMap; 00147 PMutex m_mutex; 00148 }; 00149 00151 // 00152 // 00153 // 00154 00155 class OpalMSRPManager : public PObject 00156 { 00157 public: 00158 enum { 00159 DefaultPort = 2855 00160 }; 00161 00162 // 00163 // Create an MSRP manager. This is a singleton class 00164 // 00165 OpalMSRPManager(OpalManager & opal, WORD port = DefaultPort); 00166 ~OpalMSRPManager(); 00167 00168 // 00169 // Get the local port for the MSRP manager 00170 // 00171 bool GetLocalPort(WORD & port); 00172 00173 // 00174 // Information about a connection to another MSRP manager 00175 // 00176 class Connection : public PSafeObject { 00177 public: 00178 Connection(OpalMSRPManager & manager, const std::string & key, MSRPProtocol * protocol = NULL); 00179 ~Connection(); 00180 00181 // 00182 // Start handler thread for a connection 00183 // 00184 void StartHandler(); 00185 00186 // 00187 // Handler thread for a connection 00188 // 00189 void HandlerThread(); 00190 00191 OpalMSRPManager & m_manager; 00192 std::string m_key; 00193 MSRPProtocol * m_protocol; 00194 bool m_running; 00195 PThread * m_handlerThread; 00196 bool m_originating; 00197 PAtomicInteger m_refCount; 00198 }; 00199 00200 // 00201 // Get the connection to use for communicating with a remote URL 00202 // 00203 PSafePtr<Connection> OpenConnection( 00204 const PURL & localURL, 00205 const PURL & remoteURL 00206 ); 00207 00208 // 00209 // close a connection 00210 // 00211 bool CloseConnection( 00212 PSafePtr<OpalMSRPManager::Connection> & connection 00213 ); 00214 00215 // 00216 // Create a new MSRP session ID 00217 // 00218 std::string CreateSessionID(); 00219 00220 // 00221 // return session ID as a path 00222 // 00223 PURL SessionIDToURL(const OpalTransportAddress & addr, const std::string & id); 00224 00225 // 00226 // Main listening thread for new connections 00227 // 00228 void ListenerThread(); 00229 00230 struct IncomingMSRP { 00231 int m_command; 00232 PString m_chunkId; 00233 PMIMEInfo m_mime; 00234 PString m_body; 00235 PSafePtr<Connection> m_connection; 00236 }; 00237 00238 // 00239 // dispatch an incoming MSRP message to the correct callback 00240 // 00241 void DispatchMessage( 00242 IncomingMSRP & incomingMsg 00243 ); 00244 00245 typedef PNotifierTemplate<IncomingMSRP &> CallBack; 00246 00247 void SetNotifier( 00248 const PURL & localUrl, 00249 const PURL & remoteURL, 00250 const CallBack & notifier 00251 ); 00252 00253 void RemoveNotifier( 00254 const PURL & localUrl, 00255 const PURL & remoteURL 00256 ); 00257 00258 OpalManager & GetOpalManager() { return opalManager; } 00259 00260 protected: 00261 OpalManager & opalManager; 00262 WORD m_listenerPort; 00263 PMutex mutex; 00264 PAtomicInteger lastID; 00265 PTCPSocket m_listenerSocket; 00266 PThread * m_listenerThread; 00267 00268 PMutex m_connectionInfoMapAddMutex; 00269 typedef std::map<std::string, PSafePtr<Connection> > ConnectionInfoMapType; 00270 ConnectionInfoMapType m_connectionInfoMap; 00271 00272 typedef std::map<std::string, CallBack> CallBackMap; 00273 CallBackMap m_callBacks; 00274 PMutex m_callBacksMutex; 00275 00276 private: 00277 static OpalMSRPManager * msrp; 00278 }; 00279 00281 00284 class OpalMSRPMediaSession : public OpalMediaSession 00285 { 00286 PCLASSINFO(OpalMSRPMediaSession, OpalMediaSession); 00287 public: 00288 OpalMSRPMediaSession(OpalConnection & connection, unsigned sessionId); 00289 OpalMSRPMediaSession(const OpalMSRPMediaSession & _obj); 00290 ~OpalMSRPMediaSession(); 00291 00292 bool Open(const PURL & remoteParty); 00293 00294 virtual void Close(); 00295 00296 virtual PObject * Clone() const { return new OpalMSRPMediaSession(*this); } 00297 00298 virtual bool IsActive() const { return true; } 00299 00300 virtual bool IsRTP() const { return false; } 00301 00302 virtual bool HasFailed() const { return false; } 00303 00304 virtual OpalTransportAddress GetLocalMediaAddress() const; 00305 00306 PURL GetLocalURL() const { return m_localUrl; } 00307 PURL GetRemoteURL() const { return m_remoteUrl; } 00308 void SetRemoteURL(const PURL & url) { m_remoteUrl = url; } 00309 00310 virtual void SetRemoteMediaAddress(const OpalTransportAddress &, const OpalMediaFormatList & ); 00311 00312 virtual bool WritePacket( 00313 RTP_DataFrame & frame 00314 ); 00315 00316 PBoolean ReadData( 00317 BYTE * data, 00318 PINDEX length, 00319 PINDEX & read 00320 ); 00321 00322 #if OPAL_SIP 00323 virtual SDPMediaDescription * CreateSDPMediaDescription( 00324 const OpalTransportAddress & localAddress 00325 ); 00326 #endif 00327 00328 virtual OpalMediaStream * CreateMediaStream( 00329 const OpalMediaFormat & mediaFormat, 00330 unsigned sessionID, 00331 PBoolean isSource 00332 ); 00333 00334 OpalMSRPManager & GetManager() { return m_manager; } 00335 00336 bool OpenMSRP(const PURL & remoteUrl); 00337 void CloseMSRP(); 00338 00339 void SetConnection(PSafePtr<OpalMSRPManager::Connection> & conn); 00340 00341 OpalMSRPManager & m_manager; 00342 bool m_isOriginating; 00343 std::string m_localMSRPSessionId; 00344 PURL m_localUrl; 00345 PURL m_remoteUrl; 00346 PSafePtr<OpalMSRPManager::Connection> m_connectionPtr; 00347 OpalTransportAddress m_remoteAddress; 00348 }; 00349 00351 00352 class OpalMSRPMediaStream : public OpalIMMediaStream 00353 { 00354 public: 00355 OpalMSRPMediaStream( 00356 OpalConnection & conn, 00357 const OpalMediaFormat & mediaFormat, 00358 unsigned sessionID, 00359 bool isSource, 00360 OpalMSRPMediaSession & msrpSession 00361 00362 ); 00363 00364 ~OpalMSRPMediaStream(); 00365 00366 virtual PBoolean RequiresPatchThread() const { return !isSource; } 00367 00371 virtual PBoolean ReadPacket( 00372 RTP_DataFrame & frame 00373 ); 00374 00378 virtual PBoolean WritePacket( 00379 RTP_DataFrame & frame 00380 ); 00381 00382 virtual bool Open(); 00383 virtual bool Close(); 00384 00385 PURL GetRemoteURL() const { return m_msrpSession.GetRemoteURL(); } 00386 void SetRemoteURL(const PURL & url) { m_msrpSession.SetRemoteURL(url); } 00387 00388 PDECLARE_NOTIFIER2(OpalMSRPManager, OpalMSRPMediaStream, OnReceiveMSRP, OpalMSRPManager::IncomingMSRP &); 00389 00390 00392 protected: 00393 OpalMSRPMediaSession & m_msrpSession; 00394 PString m_remoteParty; 00395 RFC4103Context m_rfc4103Context; 00396 }; 00397 00398 // schemeName,user, passwd, host, defUser,defhost, query, params, frags, path, rel, port 00399 00400 #endif // OPAL_HAS_MSRP 00401 00402 #endif // OPAL_IM_MSRP_H 00403