# 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: 27149 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2012-03-07 18:32:36 -0600 (Wed, 07 Mar 2012) $
    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
    00384     PURL GetRemoteURL() const           { return m_msrpSession.GetRemoteURL(); }
    00385     void SetRemoteURL(const PURL & url) { m_msrpSession.SetRemoteURL(url); }
    00386
    00387     PDECLARE_NOTIFIER2(OpalMSRPManager, OpalMSRPMediaStream, OnReceiveMSRP, OpalMSRPManager::IncomingMSRP &);
    00388
    00389
    00391   protected:
    00392     OpalMSRPMediaSession & m_msrpSession;
    00393     PString m_remoteParty;
    00394     RFC4103Context m_rfc4103Context;
    00395 };
    00396
    00397 //                       schemeName,user,   passwd, host,   defUser,defhost, query,  params, frags,  path,   rel,    port
    00398
    00399 #endif // OPAL_HAS_MSRP
    00400
    00401 #endif // OPAL_IM_MSRP_H
    00402