# msrp.h

Go to the documentation of this file.

    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: 28756 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2013-01-03 00:37:34 -0600 (Thu, 03 Jan 2013) $
    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
    00037 #if OPAL_HAS_MSRP
    00038
    00039 #include <opal/mediastrm.h>
    00040 #include <opal/mediasession.h>
    00041 #include <ptclib/url.h>
    00042 #include <ptclib/inetprot.h>
    00043
    00044
    00045 class OpalManager;
    00046
    00047
    00049 //
    00050 //  Ancestor for all MSRP encoding types
    00051 //
    00052
    00053 class OpalMSRPEncoding {
    00054 };
    00055
    00056
    00058 //
    00059 //  Ancestor for MSRP protocol
    00060 //
    00061
    00062 class MSRPProtocol : public PInternetProtocol
    00063 {
    00064   public:
    00065     enum Commands {
    00066       SEND,
    00067       REPORT,
    00068       NumCommands
    00069     };
    00070
    00071     static const unsigned MaximumMessageLength = 1024;
    00072
    00073     class Message
    00074     {
    00075       public:
    00076         struct Chunk {
    00077           Chunk(const PString & id, unsigned from, unsigned len)
    00078             : m_chunkId(id), m_rangeFrom(from + 1), m_rangeTo(from + len) { }
    00079
    00080           PString m_chunkId;
    00081           unsigned m_rangeFrom;
    00082           unsigned m_rangeTo;
    00083         };
    00084         typedef std::vector<Chunk> ChunkList;
    00085         ChunkList m_chunks;
    00086
    00087         PString m_id;
    00088         PURL    m_fromURL;
    00089         PURL    m_toURL;
    00090         PString m_contentType;
    00091         unsigned m_length;
    00092     };
    00093
    00094     MSRPProtocol();
    00095
    00096     bool SendSEND(
    00097       const PURL & from,
    00098       const PURL & to,
    00099       const PString & text,
    00100       const PString & contentType,
    00101       PString & messageId
    00102     );
    00103
    00104     bool SendChunk(
    00105       const PString & transactionId,
    00106       const PString toUrl,
    00107       const PString fromUrl,
    00108       const PMIMEInfo & mime,
    00109       const PString & body
    00110     );
    00111
    00112     bool SendResponse(const PString & chunkId,
    00113                              unsigned response,
    00114                       const PString & text,
    00115                       const PString & toUrl,
    00116                       const PString & fromUrl);
    00117
    00118     bool SendREPORT(const PString & chunkId,
    00119                     const PString & toUrl,
    00120                     const PString & fromUrl,
    00121                   const PMIMEInfo & mime);
    00122
    00123     bool ReadMessage(
    00124       int & command,
    00125       PString & chunkId,
    00126       PMIMEInfo & mime,
    00127       PString & body
    00128     );
    00129
    00130     //typedef std::map<std::string, Message> MessageMap;
    00131     //MessageMap m_messageMap;
    00132     PMutex m_mutex;
    00133 };
    00134
    00136 //
    00137 //
    00138 //
    00139
    00140 class OpalMSRPManager : public PObject
    00141 {
    00142   public:
    00143     enum {
    00144       DefaultPort = 2855
    00145     };
    00146
    00147     //
    00148     //  Create an MSRP manager. This is a singleton class
    00149     //
    00150     OpalMSRPManager(OpalManager & opal, WORD port = DefaultPort);
    00151     ~OpalMSRPManager();
    00152
    00153     //
    00154     //  Get the local port for the MSRP manager
    00155     //
    00156     bool GetLocalPort(WORD & port);
    00157
    00158     //
    00159     // Information about a connection to another MSRP manager
    00160     //
    00161     class Connection : public PSafeObject {
    00162       public:
    00163         Connection(OpalMSRPManager & manager, const std::string & key, MSRPProtocol * protocol = NULL);
    00164         ~Connection();
    00165
    00166         //
    00167         //  Start handler thread for a connection
    00168         //
    00169         void StartHandler();
    00170
    00171         //
    00172         //  Handler thread for a connection
    00173         //
    00174         void HandlerThread();
    00175
    00176         OpalMSRPManager & m_manager;
    00177         std::string m_key;
    00178         MSRPProtocol * m_protocol;
    00179         bool m_running;
    00180         PThread * m_handlerThread;
    00181         bool m_originating;
    00182         PAtomicInteger m_refCount;
    00183     };
    00184
    00185     //
    00186     //  Get the connection to use for communicating with a remote URL
    00187     //
    00188     PSafePtr<Connection> OpenConnection(
    00189       const PURL & localURL,
    00190       const PURL & remoteURL
    00191     );
    00192
    00193     //
    00194     //  close a connection
    00195     //
    00196     bool CloseConnection(
    00197       PSafePtr<OpalMSRPManager::Connection> & connection
    00198     );
    00199
    00200     //
    00201     //  Create a new MSRP session ID
    00202     //
    00203     std::string CreateSessionID();
    00204
    00205     //
    00206     //  return session ID as a path
    00207     //
    00208     PURL SessionIDToURL(const OpalTransportAddress & addr, const std::string & id);
    00209
    00210     //
    00211     //  Main listening thread for new connections
    00212     //
    00213     void ListenerThread();
    00214
    00215     struct IncomingMSRP {
    00216       int       m_command;
    00217       PString   m_chunkId;
    00218       PMIMEInfo m_mime;
    00219       PString   m_body;
    00220       PSafePtr<Connection> m_connection;
    00221     };
    00222
    00223     //
    00224     // dispatch an incoming MSRP message to the correct callback
    00225     //
    00226     void DispatchMessage(
    00227       IncomingMSRP & incomingMsg
    00228     );
    00229
    00230     typedef PNotifierTemplate<IncomingMSRP &> CallBack;
    00231
    00232     void SetNotifier(
    00233       const PURL & localUrl,
    00234       const PURL & remoteURL,
    00235       const CallBack & notifier
    00236     );
    00237
    00238     void RemoveNotifier(
    00239       const PURL & localUrl,
    00240       const PURL & remoteURL
    00241     );
    00242
    00243     OpalManager & GetOpalManager() { return opalManager; }
    00244
    00245   protected:
    00246     OpalManager & opalManager;
    00247     WORD m_listenerPort;
    00248     PMutex mutex;
    00249     PAtomicInteger lastID;
    00250     PTCPSocket m_listenerSocket;
    00251     PThread * m_listenerThread;
    00252
    00253     PMutex m_connectionInfoMapAddMutex;
    00254     typedef std::map<PString, PSafePtr<Connection> > ConnectionInfoMapType;
    00255     ConnectionInfoMapType m_connectionInfoMap;
    00256
    00257     typedef std::map<PString, CallBack> CallBackMap;
    00258     CallBackMap m_callBacks;
    00259     PMutex m_callBacksMutex;
    00260
    00261   private:
    00262     static OpalMSRPManager * msrp;
    00263 };
    00264
    00266
    00269 class OpalMSRPMediaSession : public OpalMediaSession
    00270 {
    00271   PCLASSINFO(OpalMSRPMediaSession, OpalMediaSession);
    00272   public:
    00273     static const PCaselessString & TCP_MSRP();
    00274
    00275     OpalMSRPMediaSession(const Init & init);
    00276     ~OpalMSRPMediaSession();
    00277
    00278     virtual PObject * Clone() const { return new OpalMSRPMediaSession(*this); }
    00279
    00280     virtual const PCaselessString & GetSessionType() const { return TCP_MSRP(); }
    00281     virtual bool Open(const PString & localInterface, const OpalTransportAddress & remoteAddress, bool isMediaAddress);
    00282     virtual bool Close();
    00283     virtual OpalTransportAddress GetLocalAddress(bool isMediaAddress = true) const;
    00284     virtual OpalTransportAddress GetRemoteAddress(bool isMediaAddress = true) const;
    00285     virtual bool SetRemoteAddress(const OpalTransportAddress & remoteAddress, bool isMediaAddress = true);
    00286 #if OPAL_SIP
    00287     virtual SDPMediaDescription * CreateSDPMediaDescription();
    00288 #endif
    00289
    00290     PURL GetLocalURL() const { return m_localUrl; }
    00291     PURL GetRemoteURL() const { return m_remoteUrl; }
    00292     void SetRemoteURL(const PURL & url) { m_remoteUrl = url; }
    00293
    00294     virtual bool WritePacket(
    00295       RTP_DataFrame & frame
    00296     );
    00297
    00298     PBoolean ReadData(
    00299       BYTE * data,
    00300       PINDEX length,
    00301       PINDEX & read
    00302     );
    00303
    00304     virtual OpalMediaStream * CreateMediaStream(
    00305       const OpalMediaFormat & mediaFormat,
    00306       unsigned sessionID,
    00307       PBoolean isSource
    00308     );
    00309
    00310     OpalMSRPManager & GetManager() { return m_manager; }
    00311
    00312     bool OpenMSRP(const PURL & remoteUrl);
    00313     void CloseMSRP();
    00314
    00315     void SetConnection(PSafePtr<OpalMSRPManager::Connection> & conn);
    00316
    00317     OpalMSRPManager & m_manager;
    00318     bool m_isOriginating;
    00319     std::string m_localMSRPSessionId;
    00320     PURL m_localUrl;
    00321     PURL m_remoteUrl;
    00322     PSafePtr<OpalMSRPManager::Connection> m_connectionPtr;
    00323     OpalTransportAddress m_remoteAddress;
    00324
    00325   private:
    00326     OpalMSRPMediaSession(const OpalMSRPMediaSession & other)
    00327       : OpalMediaSession(Init(other.m_connection, other.m_sessionId, other.m_mediaType, false)), m_manager(other.m_manager) { }
    00328     void operator=(const OpalMSRPMediaSession &) { }
    00329 };
    00330
    00331
    00333
    00334 class OpalMSRPMediaStream : public OpalMediaStream
    00335 {
    00336   public:
    00337     OpalMSRPMediaStream(
    00338       OpalConnection & conn,
    00339       const OpalMediaFormat & mediaFormat,
    00340       unsigned sessionID,
    00341       bool isSource,
    00342       OpalMSRPMediaSession & msrpSession
    00343
    00344     );
    00345
    00346     ~OpalMSRPMediaStream();
    00347
    00348     virtual PBoolean IsSynchronous() const         { return false; }
    00349     virtual PBoolean RequiresPatchThread() const   { return IsSink(); }
    00350
    00354     virtual PBoolean ReadPacket(
    00355       RTP_DataFrame & frame
    00356     );
    00357
    00361     virtual PBoolean WritePacket(
    00362       RTP_DataFrame & frame
    00363     );
    00364
    00365     virtual bool Open();
    00366
    00367     PURL GetRemoteURL() const           { return m_msrpSession.GetRemoteURL(); }
    00368     void SetRemoteURL(const PURL & url) { m_msrpSession.SetRemoteURL(url); }
    00369
    00370     PDECLARE_NOTIFIER2(OpalMSRPManager, OpalMSRPMediaStream, OnReceiveMSRP, OpalMSRPManager::IncomingMSRP &);
    00372
    00373   protected:
    00374     virtual void InternalClose() { }
    00375
    00376     OpalMSRPMediaSession & m_msrpSession;
    00377     PString                m_remoteParty;
    00378 };
    00379
    00380
    00381 #endif // OPAL_HAS_MSRP
    00382
    00383 #endif // OPAL_IM_MSRP_H
    00384