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
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
00051
00052
00053 class OpalMSRPEncoding {
00054 };
00055
00056
00058
00059
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
00131
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
00149
00150 OpalMSRPManager(OpalManager & opal, WORD port = DefaultPort);
00151 ~OpalMSRPManager();
00152
00153
00154
00155
00156 bool GetLocalPort(WORD & port);
00157
00158
00159
00160
00161 class Connection : public PSafeObject {
00162 public:
00163 Connection(OpalMSRPManager & manager, const std::string & key, MSRPProtocol * protocol = NULL);
00164 ~Connection();
00165
00166
00167
00168
00169 void StartHandler();
00170
00171
00172
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
00187
00188 PSafePtr<Connection> OpenConnection(
00189 const PURL & localURL,
00190 const PURL & remoteURL
00191 );
00192
00193
00194
00195
00196 bool CloseConnection(
00197 PSafePtr<OpalMSRPManager::Connection> & connection
00198 );
00199
00200
00201
00202
00203 std::string CreateSessionID();
00204
00205
00206
00207
00208 PURL SessionIDToURL(const OpalTransportAddress & addr, const std::string & id);
00209
00210
00211
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
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