00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00066
00067
00068 class OpalMSRPEncoding {
00069 };
00070
00071
00073
00074
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
00146
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
00164
00165 OpalMSRPManager(OpalManager & opal, WORD port = DefaultPort);
00166 ~OpalMSRPManager();
00167
00168
00169
00170
00171 bool GetLocalPort(WORD & port);
00172
00173
00174
00175
00176 class Connection : public PSafeObject {
00177 public:
00178 Connection(OpalMSRPManager & manager, const std::string & key, MSRPProtocol * protocol = NULL);
00179 ~Connection();
00180
00181
00182
00183
00184 void StartHandler();
00185
00186
00187
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
00202
00203 PSafePtr<Connection> OpenConnection(
00204 const PURL & localURL,
00205 const PURL & remoteURL
00206 );
00207
00208
00209
00210
00211 bool CloseConnection(
00212 PSafePtr<OpalMSRPManager::Connection> & connection
00213 );
00214
00215
00216
00217
00218 std::string CreateSessionID();
00219
00220
00221
00222
00223 PURL SessionIDToURL(const OpalTransportAddress & addr, const std::string & id);
00224
00225
00226
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
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
00399
00400 #endif // OPAL_HAS_MSRP
00401
00402 #endif // OPAL_IM_MSRP_H
00403