1 /* 2 * msrp.h 3 * 4 * Support for RFC 4975 Message Session Relay Protocol (MSRP) 5 * 6 * Open Phone Abstraction Library (OPAL) 7 * 8 * Copyright (c) 2008 Post Increment 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.0 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS IS" 16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 17 * the License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * The Original Code is Open Phone Abstraction Library. 21 * 22 * The Initial Developer of the Original Code is Post Increment 23 * 24 * Contributor(s): ______________________________________. 25 * 26 * $Revision: 27149 $ 27 * $Author: rjongbloed $ 28 * $Date: 2012-03-07 18:32:36 -0600 (Wed, 07 Mar 2012) $ 29 */ 30 31 #ifndef OPAL_IM_MSRP_H 32 #define OPAL_IM_MSRP_H 33 34 #include <ptlib.h> 35 #include <opal/buildopts.h> 36 #include <opal/rtpconn.h> 37 #include <opal/manager.h> 38 #include <opal/mediastrm.h> 39 #include <opal/mediatype.h> 40 #include <im/im.h> 41 #include <ptclib/inetprot.h> 42 #include <ptclib/guid.h> 43 #include <ptclib/mime.h> 44 45 #if OPAL_SIP 46 #include <sip/sdp.h> 47 #endif 48 49 #if OPAL_HAS_MSRP 50 51 class OpalMSRPMediaType : public OpalIMMediaType 52 { 53 public: 54 OpalMSRPMediaType(); 55 virtual OpalMediaSession * CreateMediaSession(OpalConnection & conn, unsigned sessionID) const; 56 57 #if OPAL_SIP 58 SDPMediaDescription * CreateSDPMediaDescription(const OpalTransportAddress & localAddress); 59 #endif 60 }; 61 62 63 //////////////////////////////////////////////////////////////////////////// 64 // 65 // Ancestor for all MSRP encoding types 66 // 67 68 class OpalMSRPEncoding { 69 }; 70 71 72 //////////////////////////////////////////////////////////////////////////// 73 // 74 // Ancestor for MSRP protocol 75 // 76 77 class MSRPProtocol : public PInternetProtocol 78 { 79 public: 80 enum Commands { 81 SEND, 82 REPORT, 83 NumCommands 84 }; 85 86 static const unsigned MaximumMessageLength = 1024; 87 88 class Message 89 { 90 public: 91 struct Chunk { ChunkChunk92 Chunk(const PString & id, unsigned from, unsigned len) 93 : m_chunkId(id), m_rangeFrom(from + 1), m_rangeTo(from + len) { } 94 95 PString m_chunkId; 96 unsigned m_rangeFrom; 97 unsigned m_rangeTo; 98 }; 99 typedef std::vector<Chunk> ChunkList; 100 ChunkList m_chunks; 101 102 PString m_id; 103 PURL m_fromURL; 104 PURL m_toURL; 105 PString m_contentType; 106 unsigned m_length; 107 }; 108 109 MSRPProtocol(); 110 111 bool SendSEND( 112 const PURL & from, 113 const PURL & to, 114 const PString & text, 115 const PString & contentType, 116 PString & messageId 117 ); 118 119 bool SendChunk( 120 const PString & transactionId, 121 const PString toUrl, 122 const PString fromUrl, 123 const PMIMEInfo & mime, 124 const PString & body 125 ); 126 127 bool SendResponse(const PString & chunkId, 128 unsigned response, 129 const PString & text, 130 const PString & toUrl, 131 const PString & fromUrl); 132 133 bool SendREPORT(const PString & chunkId, 134 const PString & toUrl, 135 const PString & fromUrl, 136 const PMIMEInfo & mime); 137 138 bool ReadMessage( 139 int & command, 140 PString & chunkId, 141 PMIMEInfo & mime, 142 PString & body 143 ); 144 145 //typedef std::map<std::string, Message> MessageMap; 146 //MessageMap m_messageMap; 147 PMutex m_mutex; 148 }; 149 150 //////////////////////////////////////////////////////////////////////////// 151 // 152 // 153 // 154 155 class OpalMSRPManager : public PObject 156 { 157 public: 158 enum { 159 DefaultPort = 2855 160 }; 161 162 // 163 // Create an MSRP manager. This is a singleton class 164 // 165 OpalMSRPManager(OpalManager & opal, WORD port = DefaultPort); 166 ~OpalMSRPManager(); 167 168 // 169 // Get the local port for the MSRP manager 170 // 171 bool GetLocalPort(WORD & port); 172 173 // 174 // Information about a connection to another MSRP manager 175 // 176 class Connection : public PSafeObject { 177 public: 178 Connection(OpalMSRPManager & manager, const std::string & key, MSRPProtocol * protocol = NULL); 179 ~Connection(); 180 181 // 182 // Start handler thread for a connection 183 // 184 void StartHandler(); 185 186 // 187 // Handler thread for a connection 188 // 189 void HandlerThread(); 190 191 OpalMSRPManager & m_manager; 192 std::string m_key; 193 MSRPProtocol * m_protocol; 194 bool m_running; 195 PThread * m_handlerThread; 196 bool m_originating; 197 PAtomicInteger m_refCount; 198 }; 199 200 // 201 // Get the connection to use for communicating with a remote URL 202 // 203 PSafePtr<Connection> OpenConnection( 204 const PURL & localURL, 205 const PURL & remoteURL 206 ); 207 208 // 209 // close a connection 210 // 211 bool CloseConnection( 212 PSafePtr<OpalMSRPManager::Connection> & connection 213 ); 214 215 // 216 // Create a new MSRP session ID 217 // 218 std::string CreateSessionID(); 219 220 // 221 // return session ID as a path 222 // 223 PURL SessionIDToURL(const OpalTransportAddress & addr, const std::string & id); 224 225 // 226 // Main listening thread for new connections 227 // 228 void ListenerThread(); 229 230 struct IncomingMSRP { 231 int m_command; 232 PString m_chunkId; 233 PMIMEInfo m_mime; 234 PString m_body; 235 PSafePtr<Connection> m_connection; 236 }; 237 238 // 239 // dispatch an incoming MSRP message to the correct callback 240 // 241 void DispatchMessage( 242 IncomingMSRP & incomingMsg 243 ); 244 245 typedef PNotifierTemplate<IncomingMSRP &> CallBack; 246 247 void SetNotifier( 248 const PURL & localUrl, 249 const PURL & remoteURL, 250 const CallBack & notifier 251 ); 252 253 void RemoveNotifier( 254 const PURL & localUrl, 255 const PURL & remoteURL 256 ); 257 GetOpalManager()258 OpalManager & GetOpalManager() { return opalManager; } 259 260 protected: 261 OpalManager & opalManager; 262 WORD m_listenerPort; 263 PMutex mutex; 264 PAtomicInteger lastID; 265 PTCPSocket m_listenerSocket; 266 PThread * m_listenerThread; 267 268 PMutex m_connectionInfoMapAddMutex; 269 typedef std::map<std::string, PSafePtr<Connection> > ConnectionInfoMapType; 270 ConnectionInfoMapType m_connectionInfoMap; 271 272 typedef std::map<std::string, CallBack> CallBackMap; 273 CallBackMap m_callBacks; 274 PMutex m_callBacksMutex; 275 276 private: 277 static OpalMSRPManager * msrp; 278 }; 279 280 //////////////////////////////////////////////////////////////////////////// 281 282 /** Class for carrying MSRP session information 283 */ 284 class OpalMSRPMediaSession : public OpalMediaSession 285 { 286 PCLASSINFO(OpalMSRPMediaSession, OpalMediaSession); 287 public: 288 OpalMSRPMediaSession(OpalConnection & connection, unsigned sessionId); 289 OpalMSRPMediaSession(const OpalMSRPMediaSession & _obj); 290 ~OpalMSRPMediaSession(); 291 292 bool Open(const PURL & remoteParty); 293 294 virtual void Close(); 295 Clone()296 virtual PObject * Clone() const { return new OpalMSRPMediaSession(*this); } 297 IsActive()298 virtual bool IsActive() const { return true; } 299 IsRTP()300 virtual bool IsRTP() const { return false; } 301 HasFailed()302 virtual bool HasFailed() const { return false; } 303 304 virtual OpalTransportAddress GetLocalMediaAddress() const; 305 GetLocalURL()306 PURL GetLocalURL() const { return m_localUrl; } GetRemoteURL()307 PURL GetRemoteURL() const { return m_remoteUrl; } SetRemoteURL(const PURL & url)308 void SetRemoteURL(const PURL & url) { m_remoteUrl = url; } 309 310 virtual void SetRemoteMediaAddress(const OpalTransportAddress &, const OpalMediaFormatList & ); 311 312 virtual bool WritePacket( 313 RTP_DataFrame & frame 314 ); 315 316 PBoolean ReadData( 317 BYTE * data, 318 PINDEX length, 319 PINDEX & read 320 ); 321 322 #if OPAL_SIP 323 virtual SDPMediaDescription * CreateSDPMediaDescription( 324 const OpalTransportAddress & localAddress 325 ); 326 #endif 327 328 virtual OpalMediaStream * CreateMediaStream( 329 const OpalMediaFormat & mediaFormat, 330 unsigned sessionID, 331 PBoolean isSource 332 ); 333 GetManager()334 OpalMSRPManager & GetManager() { return m_manager; } 335 336 bool OpenMSRP(const PURL & remoteUrl); 337 void CloseMSRP(); 338 339 void SetConnection(PSafePtr<OpalMSRPManager::Connection> & conn); 340 341 OpalMSRPManager & m_manager; 342 bool m_isOriginating; 343 std::string m_localMSRPSessionId; 344 PURL m_localUrl; 345 PURL m_remoteUrl; 346 PSafePtr<OpalMSRPManager::Connection> m_connectionPtr; 347 OpalTransportAddress m_remoteAddress; 348 }; 349 350 //////////////////////////////////////////////////////////////////////////// 351 352 class OpalMSRPMediaStream : public OpalIMMediaStream 353 { 354 public: 355 OpalMSRPMediaStream( 356 OpalConnection & conn, 357 const OpalMediaFormat & mediaFormat, ///< Media format for stream 358 unsigned sessionID, ///< Session number for stream 359 bool isSource, ///< Is a source stream 360 OpalMSRPMediaSession & msrpSession 361 362 ); 363 364 ~OpalMSRPMediaStream(); 365 RequiresPatchThread()366 virtual PBoolean RequiresPatchThread() const { return !isSource; } 367 368 /**Read raw media data from the source media stream. 369 The default behaviour reads from the PChannel object. 370 */ 371 virtual PBoolean ReadPacket( 372 RTP_DataFrame & frame 373 ); 374 375 /**Write raw media data to the sink media stream. 376 The default behaviour writes to the PChannel object. 377 */ 378 virtual PBoolean WritePacket( 379 RTP_DataFrame & frame 380 ); 381 382 virtual bool Open(); 383 GetRemoteURL()384 PURL GetRemoteURL() const { return m_msrpSession.GetRemoteURL(); } SetRemoteURL(const PURL & url)385 void SetRemoteURL(const PURL & url) { m_msrpSession.SetRemoteURL(url); } 386 387 PDECLARE_NOTIFIER2(OpalMSRPManager, OpalMSRPMediaStream, OnReceiveMSRP, OpalMSRPManager::IncomingMSRP &); 388 389 390 //@} 391 protected: 392 OpalMSRPMediaSession & m_msrpSession; 393 PString m_remoteParty; 394 RFC4103Context m_rfc4103Context; 395 }; 396 397 // schemeName,user, passwd, host, defUser,defhost, query, params, frags, path, rel, port 398 399 #endif // OPAL_HAS_MSRP 400 401 #endif // OPAL_IM_MSRP_H 402 403