OPAL  Version 3.10.10
im.h
Go to the documentation of this file.
1 /*
2  * im_mf.h
3  *
4  * Media formats for Instant Messaging
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_IM_H
32 #define OPAL_IM_IM_H
33 
34 #include <ptlib.h>
35 #include <opal/buildopts.h>
36 
37 #include <ptclib/url.h>
38 #include <ptclib/threadpool.h>
39 
40 #include <opal/transports.h>
41 
42 class OpalIM : public PObject
43 {
44  public:
45  OpalIM();
46 
47  enum Type {
49  CompositionIndication_Idle, // aka RFC 3994
51  Disposition // aka RFC 5438
52  } m_type;
53 
54  PURL m_to;
55  PURL m_from;
56  PString m_fromName;
57  PString m_mimeType;
58  PString m_body;
60 
63 
64  PAtomicInteger::IntegerType m_messageId;
65 
66  static PAtomicInteger::IntegerType GetNextMessageId();
67 };
68 
69 #if OPAL_HAS_IM
70 
71 #include <opal/mediastrm.h>
72 #include <im/rfc4103.h>
73 
75 {
76  public:
78  const char * mediaType,
79  const char * sdpType
80  )
81  : OpalMediaTypeDefinition(mediaType, sdpType, 0, OpalMediaType::DontOffer)
82  { }
83 
84  PString GetRTPEncoding() const { return PString::Empty(); }
85  RTP_UDP * CreateRTPSession(OpalRTPConnection & , unsigned , bool ) { return NULL; }
86  virtual bool UsesRTP() const { return false; }
87 };
88 
90 
91 class OpalIMManager;
92 class OpalPresentity;
93 
94 class OpalIMContext : public PSafeObject
95 {
96  PCLASSINFO(OpalIMContext, PSafeObject);
97 
98  public:
99  friend class OpalIMManager;
100 
101  OpalIMContext();
102  ~OpalIMContext();
103 
104  static PSafePtr<OpalIMContext> Create(
105  OpalManager & manager,
106  const PURL & localURL,
107  const PURL & remoteURL
108  );
109 
110  static PSafePtr<OpalIMContext> Create(
111  OpalManager & manager,
112  PSafePtr<OpalConnection> conn
113  );
114 
115  static PSafePtr<OpalIMContext> Create(
116  OpalManager & manager,
117  PSafePtr<OpalPresentity> presentity,
118  const PURL & remoteURL
119  );
120 
121  enum SentStatus {
132  };
133 
134  // send text message in this conversation
135  virtual SentStatus Send(OpalIM * message);
136  virtual SentStatus SendCompositionIndication(bool active = true);
137 
141  PAtomicInteger::IntegerType messageId;
143  };
144  virtual void OnMessageSent(const MessageSentInfo & info);
145 
146  typedef PNotifierTemplate<const MessageSentInfo &> MessageSentNotifier;
147  #define PDECLARE_MessageSentNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalIMContext, cls, fn, const MessageSentInfo &)
148  #define PCREATE_MessageSentNotifier(fn) PCREATE_NOTIFIER2(fn, const MessageSentInfo &)
149 
152  const MessageSentNotifier & notifier
153  );
154 
157  virtual SentStatus OnIncomingIM(OpalIM & message);
158 
159  typedef PNotifierTemplate<const OpalIM &> IncomingIMNotifier;
160  #define PDECLARE_IncomingIMNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalIMContext, cls, fn, const OpalIM &)
161  #define PCREATE_IncomingIMNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalIM &)
162 
165  const IncomingIMNotifier & notifier
166  );
167 
170  virtual void OnCompositionIndicationChanged(const PString & state);
171 
172  typedef PNotifierTemplate<const PString &> CompositionIndicationChangedNotifier;
173  #define PDECLARE_CompositionIndicationChangedNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalIMContext, cls, fn, const PString &)
174  #define PCREATE_CompositionIndicationChangedNotifier(fn) PCREATE_NOTIFIER2(fn, const PString &)
175 
178  const CompositionIndicationChangedNotifier & notifier
179  );
180 
181  virtual bool CheckContentType(const PString & contentType) const;
182  virtual PStringArray GetContentTypes() const;
183 
184  // start of internal functions
185 
186  PString GetID() const { return m_id; }
187  void SetID(const PString & id) { m_id = id; }
188  PString GetKey() const { return m_key; }
189  PString GetLocalURL() const { return m_localURL; }
190  PString GetRemoteURL() const { return m_remoteURL; }
191 
194 
195  PStringOptions & GetAttributes() { return m_attributes; }
196  const PStringOptions & GetAttributes() const { return m_attributes; }
197 
198  virtual bool OnNewIncomingIM();
199 
200  virtual bool AddIncomingIM(OpalIM * message);
201 
202  virtual void OnCompositionIndicationTimeout();
203 
205 
206  virtual void InternalOnMessageSent(const MessageSentInfo & info);
207 
208  static PString CreateKey(const PString & from, const PString & to);
209 
210  void ResetLastUsed();
211 
212  protected:
213  virtual SentStatus InternalSend();
214  virtual SentStatus InternalSendOutsideCall(OpalIM * message);
215  virtual SentStatus InternalSendInsideCall(OpalIM * message);
216 
221 
223  PStringOptions m_attributes;
224 
225  PSafePtr<OpalConnection> m_connection;
226  PSafePtr<OpalPresentity> m_presentity;
227 
229  PQueue<OpalIM> m_incomingMessages;
230 
233  PQueue<OpalIM> m_outgoingMessages;
234 
236  PTime m_lastUsed;
237 
238  private:
239  PString m_id, m_localURL, m_remoteURL, m_key;
240 
241 };
242 
244 {
245  public:
247 };
248 
250 {
251  public:
253 };
254 
256 
257 class OpalIMManager : public PObject
258 {
259  public:
260  OpalIMManager(OpalManager & manager);
261  ~OpalIMManager();
262 
263  class IM_Work;
264 
265  OpalIMContext::SentStatus OnIncomingMessage(OpalIM * im, PString & conversationId, PSafePtr<OpalConnection> conn = NULL);
266  void OnCompositionIndicationTimeout(const PString & conversationId);
267 
268  void AddContext(PSafePtr<OpalIMContext> context);
269  void RemoveContext(OpalIMContext * context);
270 
271  void GarbageCollection();
272 
273  PSafePtr<OpalIMContext> FindContextByIdWithLock(
274  const PString & key,
275  PSafetyMode mode = PSafeReadWrite
276  );
277 
278  PSafePtr<OpalIMContext> FindContextByNamesWithLock(
279  const PString & local,
280  const PString & remote,
281  PSafetyMode mode = PSafeReadWrite
282  );
283 
284  PSafePtr<OpalIMContext> FindContextForMessageWithLock(OpalIM & im, OpalConnection * conn = NULL);
285 
286  typedef PNotifierTemplate<OpalIMContext &> NewConversationNotifier;
287  #define PDECLARE_NewConversationNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalIMManager, cls, fn, OpalIMContext &)
288  #define PCREATE_NewConversationNotifier(fn) PCREATE_NOTIFIER2(fn, OpalIMContext &)
289 
290  class NewConversationCallBack : public PObject {
291  public:
293  PString m_scheme;
294  };
295 
296  void AddNotifier(const NewConversationNotifier & notifier, const PString & scheme);
297  bool RemoveNotifier(const NewConversationNotifier & notifier, const PString & scheme);
298 
299 
300  // thread pool declarations
301  class IM_Work
302  {
303  public:
304  IM_Work(OpalIMManager & mgr, const PString & conversationId);
305  virtual ~IM_Work();
306 
307  virtual void Work() = 0;
308 
311  };
312 
313  class NewIncomingIM_Work : public IM_Work
314  {
315  public:
316  NewIncomingIM_Work(OpalIMManager & mgr, const PString & conversationId)
317  : IM_Work(mgr, conversationId)
318  { }
319  virtual void Work()
321  };
322 
324  {
325  public:
326  NewConversation_Work(OpalIMManager & mgr, const PString & conversationId)
327  : IM_Work(mgr, conversationId)
328  { }
329  virtual void Work()
331  };
332 
333  class MessageSent_Work : public IM_Work
334  {
335  public:
336  MessageSent_Work(OpalIMManager & mgr, const PString & conversationId, const OpalIMContext::MessageSentInfo & info)
337  : IM_Work(mgr, conversationId)
338  , m_info(info)
339  { }
340  virtual void Work()
342 
344  };
345 
347  {
348  public:
349  CompositionIndicationTimeout_Work(OpalIMManager & mgr, const PString & conversationId)
350  : IM_Work(mgr, conversationId)
351  { }
352  virtual void Work()
354  };
355 
356 
357  void AddWork(IM_Work * work);
358  virtual void InternalOnNewConversation(const PString & conversation);
359  virtual void InternalOnNewIncomingIM(const PString & conversation);
360  virtual void InternalOnMessageSent(const PString & conversation, const OpalIMContext::MessageSentInfo & info);
361  virtual void InternalOnCompositionIndicationTimeout(const PString & conversationId);
362 
363  protected:
364  PQueuedThreadPool<IM_Work> m_imThreadPool;
365 
369  typedef PSafeDictionary<PString, OpalIMContext> ContextsByConversationId;
371 
373  typedef std::multimap<std::string, PString> ContextsByNames;
375 
377  PList<NewConversationCallBack> m_callbacks;
378 };
379 
381 
383 {
384  public:
385  RTP_IMFrame();
386  RTP_IMFrame(const PString & contentType);
387  RTP_IMFrame(const PString & contentType, const T140String & content);
388  RTP_IMFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true);
389 
390  void SetContentType(const PString & contentType);
391  PString GetContentType() const;
392 
393  void SetContent(const T140String & text);
394  bool GetContent(T140String & text) const;
395 
396  PString AsString() const { return PString((const char *)GetPayloadPtr(), GetPayloadSize()); }
397 };
398 
400 {
401  public:
403  OpalConnection & conn,
404  const OpalMediaFormat & mediaFormat,
405  unsigned sessionID,
406  bool isSource
407  );
408 
409  virtual PBoolean IsSynchronous() const { return false; }
410  virtual PBoolean RequiresPatchThread() const { return false; }
411 
412  bool ReadPacket(RTP_DataFrame & packet);
413  bool WritePacket(RTP_DataFrame & packet);
414 
415  protected:
416  virtual void InternalClose() { }
417 };
418 
419 #endif // OPAL_HAS_IM
420 
421 #endif // OPAL_IM_IM_H