1 /*
2  * endpoint.h
3  *
4  * Telephony endpoint abstraction
5  *
6  * Open Phone Abstraction Library (OPAL)
7  * Formally known as the Open H323 project.
8  *
9  * Copyright (c) 2001 Equivalence Pty. Ltd.
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.0 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18  * the License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * The Original Code is Open Phone Abstraction Library.
22  *
23  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24  *
25  * Contributor(s): ______________________________________.
26  *
27  * $Revision: 27984 $
28  * $Author: rjongbloed $
29  * $Date: 2012-07-10 03:24:24 -0500 (Tue, 10 Jul 2012) $
30  */
31 
32 #ifndef OPAL_OPAL_ENDPOINT_H
33 #define OPAL_OPAL_ENDPOINT_H
34 
35 #ifdef P_USE_PRAGMA
36 #pragma interface
37 #endif
38 
39 #include <opal/buildopts.h>
40 
41 #include <opal/manager.h>
42 #include <opal/mediafmt.h>
43 #include <opal/transports.h>
44 
45 class OpalCall;
46 class OpalMediaStream;
47 
48 /**This class describes an endpoint base class.
49    Each protocol (or psuedo-protocol) would create a descendant off this
50    class to manage its particular subsystem. Typically this would involve
51    listening for incoming connections and being able to set up outgoing
52    connections. Depending on exact semantics it may need to spawn many threads
53    to achieve this.
54 
55    An endpoint will also have a default set of media data formats that it can
56    support. Connections created by it would initially have the same set, but
57    according to the semantics of the underlying protocol may end up using a
58    different set.
59 
60    Various call backs are provided for points in the connection management. As
61    a rule these are passed straight on to the OpalManager for processing. An
62    application may create descendants off this class' subclasses, eg
63    H323EndPoint, to modify or monitor its behaviour but it does not have to do
64    so as all basic operations are passed to the OpalManager so only that class
65    need be subclassed.
66  */
67 class OpalEndPoint : public PObject
68 {
69     PCLASSINFO(OpalEndPoint, PObject);
70   public:
71     enum Attributes {
72       CanTerminateCall = 1,
73       SupportsE164 = 2
74     };
75 
76   /**@name Construction */
77   //@{
78     /**Create a new endpoint.
79      */
80     OpalEndPoint(
81       OpalManager & manager,          ///<  Manager of all endpoints.
82       const PCaselessString & prefix, ///<  Prefix for URL style address strings
83       unsigned attributes             ///<  Bit mask of attributes endpoint has
84     );
85 
86     /**Destroy the endpoint.
87      */
88     ~OpalEndPoint();
89 
90     /**Shut down the endpoint, this is called by the OpalManager just before
91        destroying the object and can be handy to make sure some things are
92        stopped before the vtable gets clobbered.
93       */
94     virtual void ShutDown();
95   //@}
96 
97   /**@name Overrides from PObject */
98   //@{
99     /**Standard stream print function.
100        The PObject class has a << operator defined that calls this function
101        polymorphically.
102       */
103     void PrintOn(
104       ostream & strm    ///<  Stream to output text representation
105     ) const;
106   //@}
107 
108   /**@name Listeners management */
109   //@{
110     /**Add a set of listeners to the endoint.
111        This allows for the automatic creating of incoming call connections.
112        If the list is empty then GetDefaultListeners() is used.
113 
114        Note: while the \p interfaces parameter is a string array, each element
115        of the array should be compatible with OpalTransportAddress.
116 
117        See OpalTransportAddress for more details on the syntax of an interface
118        definition.
119       */
120     PBoolean StartListeners(
121       const PStringArray & interfaces ///<  Address of interface to listen on.
122     );
123 
124     /**Add a listener to the endoint.
125        This allows for the automatic creating of incoming call connections. /
126        If the address is empty then the first entry of GetDefaultListeners() is used.
127 
128        See OpalTransportAddress for more details on the syntax of an interface
129        definition.
130       */
131     PBoolean StartListener(
132       const OpalTransportAddress & iface ///<  Address of interface to listen on.
133     );
134 
135     /**Add a listener to the endoint.
136        This allows for the automatic creating of incoming call connections. An
137        application should use OnConnectionEstablished() to monitor when calls
138        have arrived and been successfully negotiated.
139       */
140     PBoolean StartListener(
141       OpalListener * listener ///<  Transport dependent listener.
142     );
143 
144     /**Get the default listeners for the endpoint type.
145        Default behaviour returns empty list if defaultSignalPort is zero, else
146        one entry using tcp and INADDR_ANY, eg tcp$*:1720
147       */
148     virtual PStringArray GetDefaultListeners() const;
149 
150     /**Get comma separated list of transport protocols to create if
151        no explicit listeners started.
152       */
153     virtual PString GetDefaultTransport() const;
154 
155     /**Find a listener given the transport address.
156       */
157     OpalListener * FindListener(
158         const OpalTransportAddress & iface ///<  Address of interface we may be listening on.
159     );
160 
161     /** Find a listener that is compatible with the specified protocol
162      */
163     bool FindListenerForProtocol(
164       const char * proto,         ///< Protocol to findlistener, e.g "tcp" or "udp"
165       OpalTransportAddress & addr ///< Address of listner interface
166     );
167 
168     /**Stop a listener given the transport address.
169        Returns true if a listener was on that interface, and was stopped.
170       */
171     PBoolean StopListener(
172         const OpalTransportAddress & iface ///<  Address of interface we may be listening on.
173     );
174 
175     /**Remove a listener from the endoint.
176        If the listener parameter is NULL then all listeners are removed.
177       */
178     PBoolean RemoveListener(
179       OpalListener * listener ///<  Transport dependent listener.
180     );
181 
182     /**Return a list of the transport addresses for all listeners on this endpoint
183       */
184     OpalTransportAddressArray GetInterfaceAddresses(
185       PBoolean excludeLocalHost = true,       ///<  Flag to exclude 127.0.0.1
186       const OpalTransport * associatedTransport = NULL
187                           ///<  Associated transport for precedence and translation
188     );
189 
190     /**Handle new incoming connection.
191        This will either create a new connection object or utilise a previously
192        created connection on the same transport address and reference number.
193       */
194     PDECLARE_NOTIFIER(PThread, OpalEndPoint, ListenerCallback);
195 
196     /**Handle new incoming connection from listener.
197 
198        A return value of true indicates that the transport object should be
199        deleted by the caller. false indicates that something else (eg the
200        connection) has taken over responsibility for deleting the transport.
201 
202        The default behaviour just returns true.
203       */
204     virtual PBoolean NewIncomingConnection(
205       OpalTransport * transport  ///<  Transport connection came in on
206     );
207 
208     /**Call back for a new connection has been constructed.
209        This is called after CreateConnection has returned a new connection.
210        It allows an application to make any custom adjustments to the
211        connection before it begins to process the protocol. behind it.
212       */
213     virtual void OnNewConnection(
214       OpalCall & call,              ///< Call that owns the newly created connection.
215       OpalConnection & connection   ///< New connection just created
216     );
217   //@}
218 
219   /**@name Connection management */
220   //@{
221     /**Set up a connection to a remote party.
222        This is called from the OpalManager::MakeConnection() function once
223        it has determined that this is the endpoint for the protocol.
224 
225        The general form for this party parameter is:
226 
227             [proto:][alias@][transport$]address[:port]
228 
229        where the various fields will have meanings specific to the endpoint
230        type. For example, with H.323 it could be "h323:Fred@site.com" which
231        indicates a user Fred at gatekeeper size.com. Whereas for the PSTN
232        endpoint it could be "pstn:5551234" which is to call 5551234 on the
233        first available PSTN line.
234 
235        The proto field is optional when passed to a specific endpoint. If it
236        is present, however, it must agree with the endpoints protocol name or
237        false is returned.
238 
239        This function usually returns almost immediately with the connection
240        continuing to occur in a new background thread.
241 
242        If false is returned then the connection could not be established. For
243        example if a PSTN endpoint is used and the assiciated line is engaged
244        then it may return immediately. Returning a non-NULL value does not
245        mean that the connection will succeed, only that an attempt is being
246        made.
247 
248        The default behaviour is pure.
249      */
250     virtual PSafePtr<OpalConnection> MakeConnection(
251       OpalCall & call,          ///<  Owner of connection
252       const PString & party,    ///<  Remote party to call
253       void * userData = NULL,          ///<  Arbitrary data to pass to connection
254       unsigned int options = 0,     ///<  Options bit mask to pass to conneciton
255       OpalConnection::StringOptions * stringOptions = NULL ///< Options to pass to connection
256     ) = 0;
257 
258     /**Callback for outgoing connection, it is invoked after OpalLineConnection::SetUpConnection
259        This function allows the application to set up some parameters or to log some messages
260        */
261     virtual PBoolean OnSetUpConnection(OpalConnection &connection);
262 
263     /**Call back for answering an incoming call.
264        This function is used for an application to control the answering of
265        incoming calls.
266 
267        If true is returned then the connection continues. If false then the
268        connection is aborted.
269 
270        Note this function should not block for any length of time. If the
271        decision to answer the call may take some time eg waiting for a user to
272        pick up the phone, then AnswerCallPending or AnswerCallDeferred should
273        be returned.
274 
275        If an application overrides this function, it should generally call the
276        ancestor version to complete calls. Unless the application completely
277        takes over that responsibility. Generally, an application would only
278        intercept this function if it wishes to do some form of logging. For
279        this you can obtain the name of the caller by using the function
280        OpalConnection::GetRemotePartyName().
281 
282        The default behaviour calls the OpalManager function of the same name.
283      */
284     virtual PBoolean OnIncomingConnection(
285       OpalConnection & connection,  ///<  Connection that is calling
286       unsigned options,             ///<  options for new connection (can't use default value as overrides will fail)
287       OpalConnection::StringOptions * stringOptions  ///< Options to pass to connection
288     );
289 
290     /**Call back for remote party is now responsible for completing the call.
291        This function is called when the remote system has been contacted and it
292        has accepted responsibility for completing, or failing, the call. This
293        is distinct from OnAlerting() in that it is not known at this time if
294        anything is ringing. This indication may be used to distinguish between
295        "transport" level error, in which case another host may be tried, and
296        that finalising the call has moved "upstream" and the local system has
297        no more to do but await a result.
298 
299        If an application overrides this function, it should generally call the
300        ancestor version for correct operation.
301 
302        The default behaviour calls the OpalManager function of the same name.
303      */
304     virtual void OnProceeding(
305       OpalConnection & connection   ///<  Connection that is proceeeding
306     );
307 
308     /**Call back for remote party being alerted.
309        This function is called after the connection is informed that the
310        remote endpoint is "ringing". Generally some time after the
311        MakeConnection() function was called, this is function is called.
312 
313        If false is returned the connection is aborted.
314 
315        If an application overrides this function, it should generally call the
316        ancestor version for correct operation. An application would typically
317        only intercept this function if it wishes to do some form of logging.
318        For this you can obtain the name of the caller by using the function
319        OpalConnection::GetRemotePartyName().
320 
321        The default behaviour calls the OpalManager function of the same name.
322      */
323     virtual void OnAlerting(
324       OpalConnection & connection   ///<  Connection that is alerting
325     );
326 
327     /**Call back for answering an incoming call.
328        This function is called after the connection has been acknowledged
329        but before the connection is established
330 
331        This gives the application time to wait for some event before
332        signalling to the endpoint that the connection is to proceed. For
333        example the user pressing an "Answer call" button.
334 
335        If AnswerCallDenied is returned the connection is aborted and the
336        connetion specific end call PDU is sent. If AnswerCallNow is returned
337        then the connection proceeding, Finally if AnswerCallPending is returned then the
338        protocol negotiations are paused until the AnsweringCall() function is
339        called.
340 
341        The default behaviour simply returns AnswerNow.
342      */
343     virtual OpalConnection::AnswerCallResponse OnAnswerCall(
344       OpalConnection & connection,    ///<  connection that is being answered
345        const PString & caller         ///<  caller
346     );
347 
348     /**A call back function whenever a connection is "connected".
349        This indicates that a connection to an endpoint was connected. That
350        is the endpoint received acknowledgement via whatever protocol it uses
351        that the connection may now start media streams.
352 
353        In the context of H.323 this means that the CONNECT pdu has been
354        received.
355 
356        The default behaviour calls the OpalManager function of the same name.
357       */
358     virtual void OnConnected(
359       OpalConnection & connection   ///<  Connection that was established
360     );
361 
362     /**A call back function whenever a connection is established.
363        This indicates that a connection to an endpoint was established. This
364        usually occurs after OnConnected() and indicates that the connection
365        is both connected and has media flowing.
366 
367        In the context of H.323 this means that the signalling and control
368        channels are open and the TerminalCapabilitySet and MasterSlave
369        negotiations are complete.
370 
371        The default behaviour does nothing.
372       */
373     virtual void OnEstablished(
374       OpalConnection & connection   ///<  Connection that was established
375     );
376 
377     /**A call back function whenever a connection is broken.
378        This function can do any internal cleaning up and waiting on background
379        threads that may be using the connection object.
380 
381        Note that there is not a one to one relationship with the
382        OnEstablishedConnection() function. This function may be called without
383        that function being called. For example if MakeConnection() was used
384        but the call never completed.
385 
386        Classes that override this function should make sure they call the
387        ancestor version for correct operation.
388 
389        An application will not typically call this function as it is used by
390        the OpalManager during a release of the connection.
391 
392        The default behaviour removes the connection from the internal database
393        and calls the OpalManager function of the same name.
394       */
395     virtual void OnReleased(
396       OpalConnection & connection   ///<  Connection that was established
397     );
398 
399     /**A call back function whenever a connection is "held" or "retrieved".
400        This indicates that a connection to an endpoint was held, or
401        retrieved, either locally or by the remote endpoint.
402 
403        The default behaviour calls the OpalManager function of the same name.
404       */
405     virtual void OnHold(
406       OpalConnection & connection,   ///<  Connection that was held/retrieved
407       bool fromRemote,               ///<  Indicates remote has held local connection
408       bool onHold                    ///<  Indicates have just been held/retrieved.
409     );
410     virtual void OnHold(OpalConnection & connection); // For backward compatibility
411 
412     /**A call back function whenever a connection is forwarded.
413 
414        The default behaviour does nothing.
415       */
416     virtual PBoolean OnForwarded(
417       OpalConnection & connection,  ///<  Connection that was held
418       const PString & remoteParty         ///<  The new remote party
419     );
420 
421     /**A call back function to monitor the progress of a transfer.
422        When a transfer operation is initiated, the Transfer() function will
423        generally return immediately and the transfer may take some time. This
424        call back can give an indication to the application of the progress of
425        the transfer.
426        the transfer.
427 
428        For example in SIP, the OpalCall::Transfer() function will have sent a
429        REFER request to the remote party. The remote party sends us NOTIFY
430        requests about the progress of the REFER request.
431 
432        An application can now make a decision during the transfer operation
433        to short circuit the sequence, or let it continue. It can also
434        determine if the transfer did not go through, and it should "take back"
435        the call. Note no action is required to "take back" the call other than
436        indicate to the user that they are back on.
437 
438        A return value of false will immediately disconnect the current call.
439 
440        The exact format of the \p info parameter is dependent on the protocol
441        being used. As a minimum, it will always have a values info["result"]
442        and info["party"].
443 
444        The info["party"] indicates the part the \p connection is playing in
445        the transfer. This will be:
446           "A"   party being transferred
447           "B"   party initiating the transfer of "A"
448           "C"   party "A" is being transferred to
449 
450        The info["result"] will be at least one of the following:
451           "success"     Transfer completed successfully (party A or B)
452           "incoming"    New call was from a transfer (party C)
453           "started"     Transfer operation has started (party A)
454           "progress"    Transfer is in progress (party B)
455           "blind"       Transfer is blind, no further notification (party B)
456           "error"       Transfer could not begin (party B)
457           "failed"      Transfer started but did not complete (party A or B)
458 
459        For SIP, there may be an additional info["state"] containing the NOTIFY
460        subscription state, an info["code"] entry containing the 3 digit
461        code returned in the NOTIFY body and info["Referred-By"] indicating the
462        URI of party B. Other fields may also be present.
463 
464        The default behaviour calls the OpalManager function of the same name.
465        The default action of that function is to return false, thereby
466        releasing the connection if the info["result"] == "success".
467       */
468     virtual bool OnTransferNotify(
469       OpalConnection & connection,  ///< Connection being transferred.
470       const PStringToString & info  ///< Information on the transfer
471     );
472 
473     /**Clear a call.
474        This finds the call by using the token then calls the OpalCall::Clear()
475        function on it. All connections are released, and the conenctions and
476        call disposed of. Note that this function returns quickly and the
477        disposal happens at some later time by a background thread. This it is
478        safe to call this function from anywhere.
479 
480        If \p sync is not NULL then it is signalled when the calls are cleared.
481       */
482     virtual PBoolean ClearCall(
483       const PString & token,    ///<  Token for identifying connection
484       OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser, ///<  Reason for call clearing
485       PSyncPoint * sync = NULL  ///<  Sync point to wait on.
486     );
487 
488     /**Clear a current connection.
489        This hangs up the connection to a remote endpoint. Note that this function
490        is always synchronous. If \p sync is NULL then a local PSyncPoint is used.
491       */
492     virtual PBoolean ClearCallSynchronous(
493       const PString & token,    ///<  Token for identifying connection
494       OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser, ///<  Reason for call clearing
495       PSyncPoint * sync = NULL  ///<  Sync point to wait on.
496     );
497 
498     /**Clear all current connections.
499        This hangs up all the connections to remote endpoints. The wait
500        parameter is used to wait for all the calls to be cleared and their
501        memory usage cleaned up before returning. This is typically used in
502        the destructor for your descendant of H323EndPoint.
503       */
504     virtual void ClearAllCalls(
505       OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser, ///<  Reason for call clearing
506       PBoolean wait = true   ///<  Flag for wait for calls to e cleared.
507     );
508 
509     /**Find a connection that uses the specified token.
510        This searches the endpoint for the connection that contains the token
511        as provided by functions such as MakeConnection().
512       */
513     PSafePtr<OpalConnection> GetConnectionWithLock(
514       const PString & token,     ///<  Token to identify connection
515       PSafetyMode mode = PSafeReadWrite ///< Locking mode
516     ) { return connectionsActive.FindWithLock(token, mode); }
517 
518     /**Find a connection that uses the specified token.
519        This searches the endpoint for the connection that contains the token
520        as provided by functions such as MakeConnection(). If not then it
521        attempts to use the token as a OpalCall token and find a connection
522        of the same class.
523       */
524     template <class ConnClass>
525     PSafePtr<ConnClass> GetConnectionWithLockAs(
526       const PString & token,     ///<  Token to identify connection
527       PSafetyMode mode = PSafeReadWrite ///< Locking mode
528     )
529     {
530       PSafePtr<ConnClass> connection = PSafePtrCast<OpalConnection, ConnClass>(GetConnectionWithLock(token, mode));
531       if (connection == NULL) {
532         PSafePtr<OpalCall> call = manager.FindCallWithLock(token, PSafeReadOnly);
533         if (call != NULL) {
534           connection = PSafePtrCast<OpalConnection, ConnClass>(call->GetConnection(0, mode));
535           if (connection == NULL)
536             connection = PSafePtrCast<OpalConnection, ConnClass>(call->GetConnection(1, mode));
537         }
538       }
539       return connection;
540     }
541 
542     /**Get all calls current on the endpoint.
543       */
544     PStringList GetAllConnections();
545 
546     /** Get calls count on the endpoint
547       */
GetConnectionCount()548     PINDEX GetConnectionCount() const { return connectionsActive.GetSize(); }
549 
550     /**Determine if a connection is active.
551       */
552     virtual PBoolean HasConnection(
553       const PString & token   ///<  Token for identifying connection
554     );
555 
556     /**Destroy the connection.
557       */
558     virtual void DestroyConnection(
559       OpalConnection * connection  ///<  Connection to destroy
560     );
561   //@}
562 
563   /**@name Media Streams management */
564   //@{
565     /**Get the data formats this endpoint is capable of operating.
566        This provides a list of media data format names that may be used by an
567        OpalMediaStream may be created by a connection from this endpoint.
568 
569        Note that a specific connection may not actually support all of the
570        media formats returned here, but should return no more.
571 
572        The default behaviour is pure.
573       */
574     virtual OpalMediaFormatList GetMediaFormats() const = 0;
575 
576     /**Adjust media formats available on a connection.
577        This is called by a connection after it has called
578        OpalCall::GetMediaFormats() to get all media formats that it can use so
579        that an application may remove or reorder the media formats before they
580        are used to open media streams.
581 
582        The default behaviour calls the OpalManager function of the same name.
583       */
584     virtual void AdjustMediaFormats(
585       bool local,                         ///<  Media formats a local ones to be presented to remote
586       const OpalConnection & connection,  ///<  Connection that is about to use formats
587       OpalMediaFormatList & mediaFormats  ///<  Media formats to use
588     ) const;
589 
590     /**Call back when opening a media stream.
591        This function is called when a connection has created a new media
592        stream according to the logic of its underlying protocol.
593 
594        The usual requirement is that media streams are created on all other
595        connections participating in the call and all of the media streams are
596        attached to an instance of an OpalMediaPatch object that will read from
597        one of the media streams passing data to the other media streams.
598 
599        The default behaviour calls the OpalManager function of the same name.
600       */
601     virtual PBoolean OnOpenMediaStream(
602       OpalConnection & connection,  ///<  Connection that owns the media stream
603       OpalMediaStream & stream      ///<  New media stream being opened
604     );
605 
606     /**Call back for closed a media stream.
607 
608        The default behaviour calls the OpalManager function of the same name.
609       */
610     virtual void OnClosedMediaStream(
611       const OpalMediaStream & stream     ///<  Media stream being closed
612     );
613 
614 #if OPAL_VIDEO
615     /**Create an PVideoInputDevice for a source media stream.
616       */
617     virtual PBoolean CreateVideoInputDevice(
618       const OpalConnection & connection,    ///<  Connection needing created video device
619       const OpalMediaFormat & mediaFormat,  ///<  Media format for stream
620       PVideoInputDevice * & device,         ///<  Created device
621       PBoolean & autoDelete                     ///<  Flag for auto delete device
622     );
623 
624     /**Create an PVideoOutputDevice for a sink media stream or the preview
625        display for a source media stream.
626       */
627     virtual PBoolean CreateVideoOutputDevice(
628       const OpalConnection & connection,    ///<  Connection needing created video device
629       const OpalMediaFormat & mediaFormat,  ///<  Media format for stream
630       PBoolean preview,                         ///<  Flag indicating is a preview output
631       PVideoOutputDevice * & device,        ///<  Created device
632       PBoolean & autoDelete                     ///<  Flag for auto delete device
633     );
634 #endif
635   //@}
636 
637   /**@name User indications */
638   //@{
639     /**Call back for remote enpoint has sent user input as a string.
640 
641        The default behaviour calls the OpalManager function of the same name.
642       */
643     virtual void OnUserInputString(
644       OpalConnection & connection,  ///<  Connection input has come from
645       const PString & value   ///<  String value of indication
646     );
647 
648     /**Call back for remote enpoint has sent user input.
649        If duration is zero then this indicates the beginning of the tone. If
650        duration is non-zero then it indicates the end of the tone output.
651 
652        The default behaviour calls the OpalManager function of the same name.
653       */
654     virtual void OnUserInputTone(
655       OpalConnection & connection,  ///<  Connection input has come from
656       char tone,                    ///<  Tone received
657       int duration                  ///<  Duration of tone
658     );
659 
660     /**Read a sequence of user indications from connection with timeouts.
661       */
662     virtual PString ReadUserInput(
663       OpalConnection & connection,        ///<  Connection to read input from
664       const char * terminators = "#\r\n", ///<  Characters that can terminte input
665       unsigned lastDigitTimeout = 4,      ///<  Timeout on last digit in string
666       unsigned firstDigitTimeout = 30     ///<  Timeout on receiving any digits
667     );
668   //@}
669 
670   /**@name Instant Messaging */
671   //@{
672     /**Send text message
673      */
674     virtual PBoolean Message(
675       const PString & to,
676       const PString & body
677     );
678     virtual PBoolean Message(
679       const PURL & to,
680       const PString & type,
681       const PString & body,
682       PURL & from,
683       PString & conversationId
684     );
685     virtual PBoolean Message(
686       OpalIM & Message
687     );
688 
689     /**Called when text message received
690      */
691     virtual void OnMessageReceived(
692       const OpalIM & message
693     );
694   //@}
695 
696   /**@name Other services */
697   //@{
698     /**Callback called when Message Waiting Indication (MWI) is received.
699        Multiple callbacks may occur with each MessageWaitingType. A \p type
700        of NumMessageWaitingTypes indicates the server is unable to distinguish
701        the message type.
702 
703        The \p extraInfo parameter is generally of the form "a/b" where a and b
704        unsigned integers representing new and old message count. However, it
705        may be a simple "yes" or "no" if the remote cannot provide a message
706        count.
707      */
708     virtual void OnMWIReceived (
709       const PString & party,                ///< Name of party MWI is for
710       OpalManager::MessageWaitingType type, ///< Type of message that is waiting
711       const PString & extraInfo             ///< Addition information on the MWI
712     );
713 
714     /** Execute garbage collection for endpoint.
715         Returns true if all garbage has been collected.
716         Default behaviour deletes the objects in the connectionsActive list.
717       */
718     virtual PBoolean GarbageCollection();
719   //@}
720 
721   /**@name Member variable access */
722   //@{
723     /**Get the manager for this endpoint.
724      */
GetManager()725     OpalManager & GetManager() const { return manager; }
726 
727     /**Get the protocol prefix name for the endpoint.
728       */
GetPrefixName()729     const PString & GetPrefixName() const { return prefixName; }
730 
731     /**Get an indication of if this endpoint has particular option.
732       */
HasAttribute(Attributes opt)733     PBoolean HasAttribute(Attributes opt) const { return (attributeBits&opt) != 0; }
734 
735     /**Get the default signal port for this endpoint.
736      */
GetDefaultSignalPort()737     WORD GetDefaultSignalPort() const { return defaultSignalPort; }
738 
739     /**Get the product info for all endpoints.
740       */
GetProductInfo()741     const OpalProductInfo & GetProductInfo() const { return productInfo; }
742 
743     /**Set the product info for all endpoints.
744       */
SetProductInfo(const OpalProductInfo & info)745     void SetProductInfo(
746       const OpalProductInfo & info
747     ) { productInfo = info; }
748 
749     /**Get the default local party name for all connections on this endpoint.
750       */
GetDefaultLocalPartyName()751     const PString & GetDefaultLocalPartyName() const { return defaultLocalPartyName; }
752 
753     /**Set the default local party name for all connections on this endpoint.
754       */
SetDefaultLocalPartyName(const PString & name)755     virtual void SetDefaultLocalPartyName(
756       const PString & name  /// Name for local party
757     ) { defaultLocalPartyName = name; }
758 
759     /**Get the default local display name for all connections on this endpoint.
760       */
GetDefaultDisplayName()761     const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
762 
763     /**Set the default local display name for all connections on this endpoint.
764       */
SetDefaultDisplayName(const PString & name)765     void SetDefaultDisplayName(const PString & name) { defaultDisplayName = name; }
766 
767     /**Get the initial bandwidth parameter.
768      */
GetInitialBandwidth()769     unsigned GetInitialBandwidth() const { return initialBandwidth; }
770 
771     /**Get the initial bandwidth parameter.
772      */
SetInitialBandwidth(unsigned bandwidth)773     void SetInitialBandwidth(unsigned bandwidth) { initialBandwidth = bandwidth; }
774 
775     /**Get the set of listeners (incoming call transports) for this endpoint.
776      */
GetListeners()777     const OpalListenerList & GetListeners() const { return listeners; }
778 
779     /**Get the default options for created connections.
780       */
GetDefaultStringOptions()781     const OpalConnection::StringOptions & GetDefaultStringOptions() const { return m_defaultStringOptions; }
782 
783     /**Set the default options for created connections.
784       */
SetDefaultStringOptions(const OpalConnection::StringOptions & opts)785     void SetDefaultStringOptions(const OpalConnection::StringOptions & opts) { m_defaultStringOptions = opts; }
786 
787     /**Set the default option for created connections.
788       */
SetDefaultStringOption(const PCaselessString & key,const PString & data)789     void SetDefaultStringOption(const PCaselessString & key, const PString & data) { m_defaultStringOptions.SetAt(key, data); }
790 
791     /**Get the default mode for sending User Input Indications.
792       */
GetSendUserInputMode()793     OpalConnection::SendUserInputModes GetSendUserInputMode() const { return defaultSendUserInputMode; }
794 
795     /**Set the default mode for sending User Input Indications.
796       */
SetSendUserInputMode(OpalConnection::SendUserInputModes mode)797     void SetSendUserInputMode(OpalConnection::SendUserInputModes mode) { defaultSendUserInputMode = mode; }
798   //@}
799 
800 #if OPAL_PTLIB_SSL
801     /** Get the name of the file to use as SSL certificate for SSL based calls, e.g. sips or h323s
802       */
803     PString GetSSLCertificate() const;
804 #endif
805 
806   protected:
807     OpalManager   & manager;
808     PCaselessString prefixName;
809     unsigned        attributeBits;
810     WORD            defaultSignalPort;
811     PINDEX          m_maxSizeUDP;
812     OpalProductInfo productInfo;
813     PString         defaultLocalPartyName;
814     PString         defaultDisplayName;
815 
816     unsigned initialBandwidth;  // in 100s of bits/sev
817     OpalConnection::StringOptions      m_defaultStringOptions;
818     OpalConnection::SendUserInputModes defaultSendUserInputMode;
819 
820     OpalListenerList   listeners;
821 
822     class ConnectionDict : public PSafeDictionary<PString, OpalConnection>
823     {
824         virtual void DeleteObject(PObject * object) const;
825     } connectionsActive;
826     OpalConnection * AddConnection(OpalConnection * connection);
827 
828     PMutex inUseFlag;
829 
830     friend void OpalManager::GarbageCollection();
831     friend void OpalConnection::Release(CallEndReason,bool);
832 
833   private:
834     P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &, unsigned), false);
835     P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &), false);
836     P_REMOVE_VIRTUAL_VOID(AdjustMediaFormats(const OpalConnection &, OpalMediaFormatList &) const);
837     P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const PURL&,const PString&,const PURL&,const PString&,const PString&,const PString&));
838 };
839 
840 
841 /// Test for if string is a valid E.164 number
842 bool OpalIsE164(
843   const PString & number,   ///< Number to inspect
844   bool strict = false     ///< Strict interpretation, or allow leading '+'
845 );
846 
847 
848 #endif // OPAL_OPAL_ENDPOINT_H
849 
850 
851 // End of File ///////////////////////////////////////////////////////////////
852