diff options
Diffstat (limited to 'pjsip/include/pjsua2/endpoint.hpp')
-rw-r--r-- | pjsip/include/pjsua2/endpoint.hpp | 1322 |
1 files changed, 1322 insertions, 0 deletions
diff --git a/pjsip/include/pjsua2/endpoint.hpp b/pjsip/include/pjsua2/endpoint.hpp new file mode 100644 index 00000000..5ccd533b --- /dev/null +++ b/pjsip/include/pjsua2/endpoint.hpp @@ -0,0 +1,1322 @@ +/* $Id$ */ +/* + * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PJSUA2_UA_HPP__ +#define __PJSUA2_UA_HPP__ + +/** + * @file pjsua2/endpoint.hpp + * @brief PJSUA2 Base Agent Operation + */ +#include <pjsua2/persistent.hpp> +#include <pjsua2/media.hpp> +#include <pjsua2/siptypes.hpp> +#include <list> + +/** PJSUA2 API is inside pj namespace */ +namespace pj +{ + +/** + * @defgroup PJSUA2_UA Endpoint + * @ingroup PJSUA2_Ref + * @{ + */ + +using std::string; +using std::vector; + + +////////////////////////////////////////////////////////////////////////////// + +/** + * Argument to Endpoint::onNatDetectionComplete() callback. + */ +struct OnNatDetectionCompleteParam +{ + /** + * Status of the detection process. If this value is not PJ_SUCCESS, + * the detection has failed and \a nat_type field will contain + * PJ_STUN_NAT_TYPE_UNKNOWN. + */ + pj_status_t status; + + /** + * The text describing the status, if the status is not PJ_SUCCESS. + */ + string reason; + + /** + * This contains the NAT type as detected by the detection procedure. + * This value is only valid when the \a status is PJ_SUCCESS. + */ + pj_stun_nat_type natType; + + /** + * Text describing that NAT type. + */ + string natTypeName; + +}; + +/** + * Argument to Endpoint::onNatCheckStunServersComplete() callback. + */ +struct OnNatCheckStunServersCompleteParam +{ + /** + * Arbitrary user data that was passed to Endpoint::natCheckStunServers() + * function. + */ + Token userData; + + /** + * This will contain PJ_SUCCESS if at least one usable STUN server + * is found, otherwise it will contain the last error code during + * the operation. + */ + pj_status_t status; + + /** + * The server name that yields successful result. This will only + * contain value if status is successful. + */ + string name; + + /** + * The server IP address and port in "IP:port" format. This will only + * contain value if status is successful. + */ + SocketAddress addr; +}; + +/** + * Parameter of Endpoint::onTimer() callback. + */ +struct OnTimerParam +{ + /** + * Arbitrary user data that was passed to Endpoint::utilTimerSchedule() + * function. + */ + Token userData; + + /** + * The interval of this timer, in miliseconds. + */ + unsigned msecDelay; +}; + +/** + * Parameter of Endpoint::onTransportState() callback. + */ +struct OnTransportStateParam +{ + /** + * The transport handle. + */ + TransportHandle hnd; + + /** + * Transport current state. + */ + pjsip_transport_state state; + + /** + * The last error code related to the transport state. + */ + pj_status_t lastError; +}; + +/** + * Parameter of Endpoint::onSelectAccount() callback. + */ +struct OnSelectAccountParam +{ + /** + * The incoming request. + */ + SipRxData rdata; + + /** + * The account index to be used to handle the request. + * Upon entry, this will be filled by the account index + * chosen by the library. Application may change it to + * another value to use another account. + */ + int accountIndex; +}; + +////////////////////////////////////////////////////////////////////////////// +/** + * SIP User Agent related settings. + */ +struct UaConfig : public PersistentObject +{ + /** + * Maximum calls to support (default: 4). The value specified here + * must be smaller than the compile time maximum settings + * PJSUA_MAX_CALLS, which by default is 32. To increase this + * limit, the library must be recompiled with new PJSUA_MAX_CALLS + * value. + */ + unsigned maxCalls; + + /** + * Number of worker threads. Normally application will want to have at + * least one worker thread, unless when it wants to poll the library + * periodically, which in this case the worker thread can be set to + * zero. + */ + unsigned threadCnt; + + /** + * When this flag is non-zero, all callbacks that come from thread + * other than main thread will be posted to the main thread and + * to be executed by Endpoint::libHandleEvents() function. This + * includes the logging callback. Note that this will only work if + * threadCnt is set to zero and Endpoint::libHandleEvents() is + * performed by main thread. By default, the main thread is set + * from the thread that invoke Endpoint::libCreate() + * + * Default: false + */ + bool mainThreadOnly; + + /** + * Array of nameservers to be used by the SIP resolver subsystem. + * The order of the name server specifies the priority (first name + * server will be used first, unless it is not reachable). + */ + StringVector nameserver; + + /** + * Optional user agent string (default empty). If it's empty, no + * User-Agent header will be sent with outgoing requests. + */ + string userAgent; + + /** + * Array of STUN servers to try. The library will try to resolve and + * contact each of the STUN server entry until it finds one that is + * usable. Each entry may be a domain name, host name, IP address, and + * it may contain an optional port number. For example: + * - "pjsip.org" (domain name) + * - "sip.pjsip.org" (host name) + * - "pjsip.org:33478" (domain name and a non-standard port number) + * - "10.0.0.1:3478" (IP address and port number) + * + * When nameserver is configured in the \a pjsua_config.nameserver field, + * if entry is not an IP address, it will be resolved with DNS SRV + * resolution first, and it will fallback to use DNS A resolution if this + * fails. Port number may be specified even if the entry is a domain name, + * in case the DNS SRV resolution should fallback to a non-standard port. + * + * When nameserver is not configured, entries will be resolved with + * pj_gethostbyname() if it's not an IP address. Port number may be + * specified if the server is not listening in standard STUN port. + */ + StringVector stunServer; + + /** + * This specifies if the library startup should ignore failure with the + * STUN servers. If this is set to PJ_FALSE, the library will refuse to + * start if it fails to resolve or contact any of the STUN servers. + * + * Default: TRUE + */ + bool stunIgnoreFailure; + + /** + * Support for adding and parsing NAT type in the SDP to assist + * troubleshooting. The valid values are: + * - 0: no information will be added in SDP, and parsing is disabled. + * - 1: only the NAT type number is added. + * - 2: add both NAT type number and name. + * + * Default: 1 + */ + int natTypeInSdp; + + /** + * Handle unsolicited NOTIFY requests containing message waiting + * indication (MWI) info. Unsolicited MWI is incoming NOTIFY requests + * which are not requested by client with SUBSCRIBE request. + * + * If this is enabled, the library will respond 200/OK to the NOTIFY + * request and forward the request to Endpoint::onMwiInfo() callback. + * + * See also AccountMwiConfig.enabled. + * + * Default: PJ_TRUE + */ + bool mwiUnsolicitedEnabled; + +public: + /** + * Default constructor to initialize with default values. + */ + UaConfig(); + + /** + * Construct from pjsua_config. + */ + void fromPj(const pjsua_config &ua_cfg); + + /** + * Export to pjsua_config + */ + pjsua_config toPj() const; + + /** + * Read this object from a container. + * + * @param node Container to write values from. + */ + virtual void readObject(const ContainerNode &node) throw(Error); + + /** + * Write this object to a container. + * + * @param node Container to write values to. + */ + virtual void writeObject(ContainerNode &node) const throw(Error); + +}; + + +/** + * Data containing log entry to be written by the LogWriter. + */ +struct LogEntry +{ + /** Log verbosity level of this message */ + int level; + + /** The log message */ + string msg; + + /** ID of current thread */ + long threadId; + + /** The name of the thread that writes this log */ + string threadName; +}; + + +/** + * Interface for writing log messages. Applications can inherit this class + * and supply it in the LogConfig structure to implement custom log + * writing facility. + */ +class LogWriter +{ +public: + /** Destructor */ + virtual ~LogWriter() {} + + /** Write a log entry. */ + virtual void write(const LogEntry &entry) = 0; +}; + + +/** + * Logging configuration, which can be (optionally) specified when calling + * Lib::init(). + */ +struct LogConfig : public PersistentObject +{ + /** Log incoming and outgoing SIP message? Yes! */ + unsigned msgLogging; + + /** Input verbosity level. Value 5 is reasonable. */ + unsigned level; + + /** Verbosity level for console. Value 4 is reasonable. */ + unsigned consoleLevel; + + /** Log decoration. */ + unsigned decor; + + /** Optional log filename if app wishes the library to write to log file. + */ + string filename; + + /** + * Additional flags to be given to pj_file_open() when opening + * the log file. By default, the flag is PJ_O_WRONLY. Application + * may set PJ_O_APPEND here so that logs are appended to existing + * file instead of overwriting it. + * + * Default is 0. + */ + unsigned fileFlags; + + /** + * Custom log writer, if required. This instance will be destroyed + * by the endpoint when the endpoint is destroyed. + */ + LogWriter *writer; + +public: + /** Default constructor initialises with default values */ + LogConfig(); + + /** Construct from pjsua_logging_config */ + void fromPj(const pjsua_logging_config &lc); + + /** Generate pjsua_logging_config. */ + pjsua_logging_config toPj() const; + + /** + * Read this object from a container. + * + * @param node Container to write values from. + */ + virtual void readObject(const ContainerNode &node) throw(Error); + + /** + * Write this object to a container. + * + * @param node Container to write values to. + */ + virtual void writeObject(ContainerNode &node) const throw(Error); +}; + + +/** + * This structure describes media configuration, which will be specified + * when calling Lib::init(). + */ +struct MediaConfig : public PersistentObject +{ +public: + /** + * Clock rate to be applied to the conference bridge. + * If value is zero, default clock rate will be used + * (PJSUA_DEFAULT_CLOCK_RATE, which by default is 16KHz). + */ + unsigned clockRate; + + /** + * Clock rate to be applied when opening the sound device. + * If value is zero, conference bridge clock rate will be used. + */ + unsigned sndClockRate; + + /** + * Channel count be applied when opening the sound device and + * conference bridge. + */ + unsigned channelCount; + + /** + * Specify audio frame ptime. The value here will affect the + * samples per frame of both the sound device and the conference + * bridge. Specifying lower ptime will normally reduce the + * latency. + * + * Default value: PJSUA_DEFAULT_AUDIO_FRAME_PTIME + */ + unsigned audioFramePtime; + + /** + * Specify maximum number of media ports to be created in the + * conference bridge. Since all media terminate in the bridge + * (calls, file player, file recorder, etc), the value must be + * large enough to support all of them. However, the larger + * the value, the more computations are performed. + * + * Default value: PJSUA_MAX_CONF_PORTS + */ + unsigned maxMediaPorts; + + /** + * Specify whether the media manager should manage its own + * ioqueue for the RTP/RTCP sockets. If yes, ioqueue will be created + * and at least one worker thread will be created too. If no, + * the RTP/RTCP sockets will share the same ioqueue as SIP sockets, + * and no worker thread is needed. + * + * Normally application would say yes here, unless it wants to + * run everything from a single thread. + */ + bool hasIoqueue; + + /** + * Specify the number of worker threads to handle incoming RTP + * packets. A value of one is recommended for most applications. + */ + unsigned threadCnt; + + /** + * Media quality, 0-10, according to this table: + * 5-10: resampling use large filter, + * 3-4: resampling use small filter, + * 1-2: resampling use linear. + * The media quality also sets speex codec quality/complexity to the + * number. + * + * Default: 5 (PJSUA_DEFAULT_CODEC_QUALITY). + */ + unsigned quality; + + /** + * Specify default codec ptime. + * + * Default: 0 (codec specific) + */ + unsigned ptime; + + /** + * Disable VAD? + * + * Default: 0 (no (meaning VAD is enabled)) + */ + bool noVad; + + /** + * iLBC mode (20 or 30). + * + * Default: 30 (PJSUA_DEFAULT_ILBC_MODE) + */ + unsigned ilbcMode; + + /** + * Percentage of RTP packet to drop in TX direction + * (to simulate packet lost). + * + * Default: 0 + */ + unsigned txDropPct; + + /** + * Percentage of RTP packet to drop in RX direction + * (to simulate packet lost). + * + * Default: 0 + */ + unsigned rxDropPct; + + /** + * Echo canceller options (see pjmedia_echo_create()) + * + * Default: 0. + */ + unsigned ecOptions; + + /** + * Echo canceller tail length, in miliseconds. Setting this to zero + * will disable echo cancellation. + * + * Default: PJSUA_DEFAULT_EC_TAIL_LEN + */ + unsigned ecTailLen; + + /** + * Audio capture buffer length, in milliseconds. + * + * Default: PJMEDIA_SND_DEFAULT_REC_LATENCY + */ + unsigned sndRecLatency; + + /** + * Audio playback buffer length, in milliseconds. + * + * Default: PJMEDIA_SND_DEFAULT_PLAY_LATENCY + */ + unsigned sndPlayLatency; + + /** + * Jitter buffer initial prefetch delay in msec. The value must be + * between jb_min_pre and jb_max_pre below. + * + * Default: -1 (to use default stream settings, currently 150 msec) + */ + int jbInit; + + /** + * Jitter buffer minimum prefetch delay in msec. + * + * Default: -1 (to use default stream settings, currently 60 msec) + */ + int jbMinPre; + + /** + * Jitter buffer maximum prefetch delay in msec. + * + * Default: -1 (to use default stream settings, currently 240 msec) + */ + int jbMaxPre; + + /** + * Set maximum delay that can be accomodated by the jitter buffer msec. + * + * Default: -1 (to use default stream settings, currently 360 msec) + */ + int jbMax; + + /** + * Specify idle time of sound device before it is automatically closed, + * in seconds. Use value -1 to disable the auto-close feature of sound + * device + * + * Default : 1 + */ + int sndAutoCloseTime; + + /** + * Specify whether built-in/native preview should be used if available. + * In some systems, video input devices have built-in capability to show + * preview window of the device. Using this built-in preview is preferable + * as it consumes less CPU power. If built-in preview is not available, + * the library will perform software rendering of the input. If this + * field is set to PJ_FALSE, software preview will always be used. + * + * Default: PJ_TRUE + */ + bool vidPreviewEnableNative; + +public: + /** Default constructor initialises with default values */ + MediaConfig(); + + /** Construct from pjsua_media_config. */ + void fromPj(const pjsua_media_config &mc); + + /** Export */ + pjsua_media_config toPj() const; + + /** + * Read this object from a container. + * + * @param node Container to write values from. + */ + virtual void readObject(const ContainerNode &node) throw(Error); + + /** + * Write this object to a container. + * + * @param node Container to write values to. + */ + virtual void writeObject(ContainerNode &node) const throw(Error); +}; + + +/** + * Endpoint configuration + */ +struct EpConfig : public PersistentObject +{ + /** UA config */ + UaConfig uaConfig; + + /** Logging config */ + LogConfig logConfig; + + /** Media config */ + MediaConfig medConfig; + + /** + * Read this object from a container. + * + * @param node Container to write values from. + */ + virtual void readObject(const ContainerNode &node) throw(Error); + + /** + * Write this object to a container. + * + * @param node Container to write values to. + */ + virtual void writeObject(ContainerNode &node) const throw(Error); + +}; + +/* This represents posted job */ +struct PendingJob +{ + /** Perform the job */ + virtual void execute(bool is_pending) = 0; + + /** Virtual destructor */ + virtual ~PendingJob() {} +}; + +////////////////////////////////////////////////////////////////////////////// + +/** + * Endpoint represents an instance of pjsua library. There can only be + * one instance of pjsua library in an application, hence this class + * is a singleton. + */ +class Endpoint +{ +public: + /** Retrieve the singleton instance of the endpoint */ + static Endpoint &instance() throw(Error); + + /** Default constructor */ + Endpoint(); + + /** Virtual destructor */ + virtual ~Endpoint(); + + + /************************************************************************* + * Base library operations + */ + + /** + * Get library version. + */ + Version libVersion() const; + + /** + * Instantiate pjsua application. Application must call this function before + * calling any other functions, to make sure that the underlying libraries + * are properly initialized. Once this function has returned success, + * application must call destroy() before quitting. + */ + void libCreate() throw(Error); + + /** + * Get library state. + * + * @return library state. + */ + pjsua_state libGetState() const; + + /** + * Initialize pjsua with the specified settings. All the settings are + * optional, and the default values will be used when the config is not + * specified. + * + * Note that create() MUST be called before calling this function. + * + * @param prmEpConfig Endpoint configurations + */ + void libInit( const EpConfig &prmEpConfig) throw(Error); + + /** + * Call this function after all initialization is done, so that the + * library can do additional checking set up. Application may call this + * function any time after init(). + */ + void libStart() throw(Error); + + /** + * Register a thread to poll for events. This function should be + * called by an external worker thread, and it will block polling + * for events until the library is destroyed. + */ + void libRegisterWorkerThread(const string &name) throw(Error); + + /** + * Stop all worker threads. + */ + void libStopWorkerThreads(); + + /** + * Poll pjsua for events, and if necessary block the caller thread for + * the specified maximum interval (in miliseconds). + * + * Application doesn't normally need to call this function if it has + * configured worker thread (\a thread_cnt field) in pjsua_config + * structure, because polling then will be done by these worker threads + * instead. + * + * If EpConfig::UaConfig::mainThreadOnly is enabled and this function + * is called from the main thread (by default the main thread is thread + * that calls libCreate()), this function will also scan and run any + * pending jobs in the list. + * + * @param msec_timeout Maximum time to wait, in miliseconds. + * + * @return The number of events that have been handled during the + * poll. Negative value indicates error, and application + * can retrieve the error as (status = -return_value). + */ + int libHandleEvents(unsigned msec_timeout); + + /** + * Destroy pjsua. Application is recommended to perform graceful shutdown + * before calling this function (such as unregister the account from the + * SIP server, terminate presense subscription, and hangup active calls), + * however, this function will do all of these if it finds there are + * active sessions that need to be terminated. This function will + * block for few seconds to wait for replies from remote. + * + * Application.may safely call this function more than once if it doesn't + * keep track of it's state. + * + * @param prmFlags Combination of pjsua_destroy_flag enumeration. + */ + void libDestroy(unsigned prmFlags=0) throw(Error); + + + /************************************************************************* + * Utilities + */ + + /** + * Retrieve the error string for the specified status code. + * + * @param prmErr The error code. + */ + string utilStrError(pj_status_t prmErr); + + /** + * Write a log message. + * + * @param prmLevel Log verbosity level (1-5) + * @param prmSender The log sender. + * @param prmMsg The log message. + */ + void utilLogWrite(int prmLevel, + const string &prmSender, + const string &prmMsg); + + /** + * Write a log entry. + * + * @param e The log entry. + */ + void utilLogWrite(LogEntry &e); + + /** + * This is a utility function to verify that valid SIP url is given. If the + * URL is a valid SIP/SIPS scheme, PJ_SUCCESS will be returned. + * + * @param prmUri The URL string. + * + * @return PJ_SUCCESS on success, or the appropriate error + * code. + * + * @see utilVerifyUri() + */ + pj_status_t utilVerifySipUri(const string &prmUri); + + /** + * This is a utility function to verify that valid URI is given. Unlike + * utilVerifySipUri(), this function will return PJ_SUCCESS if tel: URI + * is given. + * + * @param prmUri The URL string. + * + * @return PJ_SUCCESS on success, or the appropriate error + * code. + * + * @see pjsua_verify_sip_url() + */ + pj_status_t utilVerifyUri(const string &prmUri); + + /** + * Schedule a timer with the specified interval and user data. When the + * interval elapsed, onTimer() callback will be + * called. Note that the callback may be executed by different thread, + * depending on whether worker thread is enabled or not. + * + * @param prmMsecDelay The time interval in msec. + * @param prmUserData Arbitrary user data, to be given back to + * application in the callback. + * + * @return Token to identify the timer, which could be + * given to utilTimerCancel(). + */ + Token utilTimerSchedule(unsigned prmMsecDelay, + Token prmUserData) throw (Error); + + /** + * Cancel previously scheduled timer with the specified timer token. + * + * @param prmToken The timer token, which was returned from + * previous utilTimerSchedule() call. + */ + void utilTimerCancel(Token prmToken); + + /** + * Utility to register a pending job to be executed by main thread. + * If EpConfig::UaConfig::mainThreadOnly is false, the job will be + * executed immediately. + * + * @param job The job class. + */ + void utilAddPendingJob(PendingJob *job); + + /** + * Get cipher list supported by SSL/TLS backend. + */ + IntVector utilSslGetAvailableCiphers() throw (Error); + + /************************************************************************* + * NAT operations + */ + /** + * This is a utility function to detect NAT type in front of this endpoint. + * Once invoked successfully, this function will complete asynchronously + * and report the result in onNatDetectionComplete(). + * + * After NAT has been detected and the callback is called, application can + * get the detected NAT type by calling natGetType(). Application + * can also perform NAT detection by calling natDetectType() + * again at later time. + * + * Note that STUN must be enabled to run this function successfully. + */ + void natDetectType(void) throw(Error); + + /** + * Get the NAT type as detected by natDetectType() function. This + * function will only return useful NAT type after natDetectType() + * has completed successfully and onNatDetectionComplete() + * callback has been called. + * + * Exception: if this function is called while detection is in progress, + * PJ_EPENDING exception will be raised. + */ + pj_stun_nat_type natGetType() throw(Error); + + /** + * Auxiliary function to resolve and contact each of the STUN server + * entries (sequentially) to find which is usable. The libInit() must + * have been called before calling this function. + * + * @param prmServers Array of STUN servers to try. The endpoint + * will try to resolve and contact each of the + * STUN server entry until it finds one that is + * usable. Each entry may be a domain name, host + * name, IP address, and it may contain an + * optional port number. For example: + * - "pjsip.org" (domain name) + * - "sip.pjsip.org" (host name) + * - "pjsip.org:33478" (domain name and a non- + * standard port number) + * - "10.0.0.1:3478" (IP address and port number) + * @param prmWait Specify if the function should block until + * it gets the result. In this case, the function + * will block while the resolution is being done, + * and the callback will be called before this + * function returns. + * @param prmUserData Arbitrary user data to be passed back to + * application in the callback. + * + * @see natCancelCheckStunServers() + */ + void natCheckStunServers(const StringVector &prmServers, + bool prmWait, + Token prmUserData) throw(Error); + + /** + * Cancel pending STUN resolution which match the specified token. + * + * @param token The token to match. This token was given to + * natCheckStunServers() + * @param notify_cb Boolean to control whether the callback should + * be called for cancelled resolutions. When the + * callback is called, the status in the result + * will be set as PJ_ECANCELLED. + * + * Exception: PJ_ENOTFOUND if there is no matching one, or other error. + */ + void natCancelCheckStunServers(Token token, + bool notify_cb = false) throw(Error); + + /************************************************************************* + * Transport operations + */ + + /** + * Create and start a new SIP transport according to the specified + * settings. + * + * @param type Transport type. + * @param cfg Transport configuration. + * + * @return The transport ID. + */ + TransportId transportCreate(pjsip_transport_type_e type, + const TransportConfig &cfg) throw(Error); + + /** + * Enumerate all transports currently created in the system. This + * function will return all transport IDs, and application may then + * call transportGetInfo() function to retrieve detailed information + * about the transport. + * + * @return Array of transport IDs. + */ + IntVector transportEnum() throw(Error); + + /** + * Get information about transport. + * + * @param id Transport ID. + * + * @return Transport info. + */ + TransportInfo transportGetInfo(TransportId id) throw(Error); + + /** + * Disable a transport or re-enable it. By default transport is always + * enabled after it is created. Disabling a transport does not necessarily + * close the socket, it will only discard incoming messages and prevent + * the transport from being used to send outgoing messages. + * + * @param id Transport ID. + * @param enabled Enable or disable the transport. + * + */ + void transportSetEnable(TransportId id, bool enabled) throw(Error); + + /** + * Close the transport. The system will wait until all transactions are + * closed while preventing new users from using the transport, and will + * close the transport when its usage count reaches zero. + * + * @param id Transport ID. + */ + void transportClose(TransportId id) throw(Error); + + /************************************************************************* + * Call operations + */ + + /** + * Terminate all calls. This will initiate call hangup for all + * currently active calls. + */ + void hangupAllCalls(void); + + /************************************************************************* + * Media operations + */ + + /** + * Add media to the media list. + * + * @param media media to be added. + */ + void mediaAdd(AudioMedia &media); + + /** + * Remove media from the media list. + * + * @param media media to be removed. + */ + void mediaRemove(AudioMedia &media); + + /** + * Check if media has been added to the media list. + * + * @param media media to be check. + * + * @return True if media has been added, false otherwise. + */ + bool mediaExists(const AudioMedia &media) const; + + /** + * Get maximum number of media port. + * + * @return Maximum number of media port in the conference bridge. + */ + unsigned mediaMaxPorts() const; + + /** + * Get current number of active media port in the bridge. + * + * @return The number of active media port. + */ + unsigned mediaActivePorts() const; + + /** + * Enumerate all media port. + * + * @return The list of media port. + */ + const AudioMediaVector &mediaEnumPorts() const throw(Error); + + /** + * Get the instance of Audio Device Manager. + * + * @return The Audio Device Manager. + */ + AudDevManager &audDevManager(); + + /************************************************************************* + * Codec management operations + */ + + /** + * Enum all supported codecs in the system. + * + * @return Array of codec info. + */ + const CodecInfoVector &codecEnum() throw(Error); + + /** + * Change codec priority. + * + * @param codec_id Codec ID, which is a string that uniquely identify + * the codec (such as "speex/8000"). + * @param priority Codec priority, 0-255, where zero means to disable + * the codec. + * + */ + void codecSetPriority(const string &codec_id, + pj_uint8_t priority) throw(Error); + + /** + * Get codec parameters. + * + * @param codec_id Codec ID. + * + * @return Codec parameters. If codec is not found, Error + * will be thrown. + * + */ + CodecParam codecGetParam(const string &codec_id) const throw(Error); + + /** + * Set codec parameters. + * + * @param codec_id Codec ID. + * @param param Codec parameter to set. Set to NULL to reset + * codec parameter to library default settings. + * + */ + void codecSetParam(const string &codec_id, + const CodecParam param) throw(Error); + + +public: + /* + * Overrideables callbacks + */ + + /** + * Callback when the Endpoint has finished performing NAT type + * detection that is initiated with natDetectType(). + * + * @param prm Callback parameters containing the detection + * result. + */ + virtual void onNatDetectionComplete( + const OnNatDetectionCompleteParam &prm) + { PJ_UNUSED_ARG(prm); } + + /** + * Callback when the Endpoint has finished performing STUN server + * checking that is initiated with natCheckStunServers(). + * + * @param prm Callback parameters. + */ + virtual void onNatCheckStunServersComplete( + const OnNatCheckStunServersCompleteParam &prm) + { PJ_UNUSED_ARG(prm); } + + /** + * This callback is called when transport state has changed. + * + * @param prm Callback parameters. + */ + virtual void onTransportState( + const OnTransportStateParam &prm) + { PJ_UNUSED_ARG(prm); } + + /** + * Callback when a timer has fired. The timer was scheduled by + * utilTimerSchedule(). + * + * @param prm Callback parameters. + */ + virtual void onTimer(const OnTimerParam &prm) + { PJ_UNUSED_ARG(prm); } + + /** + * This callback can be used by application to override the account + * to be used to handle an incoming message. Initially, the account to + * be used will be calculated automatically by the library. This initial + * account will be used if application does not implement this callback, + * or application sets an invalid account upon returning from this + * callback. + * + * Note that currently the incoming messages requiring account assignment + * are INVITE, MESSAGE, SUBSCRIBE, and unsolicited NOTIFY. This callback + * may be called before the callback of the SIP event itself, i.e: + * incoming call, pager, subscription, or unsolicited-event. + * + * @param prm Callback parameters. + */ + virtual void onSelectAccount(OnSelectAccountParam &prm) + { PJ_UNUSED_ARG(prm); } + +private: + static Endpoint *instance_; // static instance + LogWriter *writer; // Custom writer, if any + AudioMediaVector mediaList; + AudDevManager audioDevMgr; + CodecInfoVector codecInfoList; + + /* Pending logging */ + bool mainThreadOnly; + void *mainThread; + unsigned pendingJobSize; + std::list<PendingJob*> pendingJobs; + + void performPendingJobs(); + + /* Endpoint static callbacks */ + static void logFunc(int level, const char *data, int len); + static void stun_resolve_cb(const pj_stun_resolve_result *result); + static void on_timer(pj_timer_heap_t *timer_heap, + struct pj_timer_entry *entry); + static void on_nat_detect(const pj_stun_nat_detect_result *res); + static void on_transport_state(pjsip_transport *tp, + pjsip_transport_state state, + const pjsip_transport_state_info *info); + +private: + /* + * Account & Call lookups + */ + static Account *lookupAcc(int acc_id, const char *op); + static Call *lookupCall(int call_id, const char *op); + + /* static callbacks */ + static void on_incoming_call(pjsua_acc_id acc_id, + pjsua_call_id call_id, + pjsip_rx_data *rdata); + static void on_reg_started(pjsua_acc_id acc_id, + pj_bool_t renew); + static void on_reg_state2(pjsua_acc_id acc_id, + pjsua_reg_info *info); + static void on_incoming_subscribe(pjsua_acc_id acc_id, + pjsua_srv_pres *srv_pres, + pjsua_buddy_id buddy_id, + const pj_str_t *from, + pjsip_rx_data *rdata, + pjsip_status_code *code, + pj_str_t *reason, + pjsua_msg_data *msg_data); + static void on_pager2(pjsua_call_id call_id, + const pj_str_t *from, + const pj_str_t *to, + const pj_str_t *contact, + const pj_str_t *mime_type, + const pj_str_t *body, + pjsip_rx_data *rdata, + pjsua_acc_id acc_id); + static void on_pager_status2(pjsua_call_id call_id, + const pj_str_t *to, + const pj_str_t *body, + void *user_data, + pjsip_status_code status, + const pj_str_t *reason, + pjsip_tx_data *tdata, + pjsip_rx_data *rdata, + pjsua_acc_id acc_id); + static void on_typing2(pjsua_call_id call_id, + const pj_str_t *from, + const pj_str_t *to, + const pj_str_t *contact, + pj_bool_t is_typing, + pjsip_rx_data *rdata, + pjsua_acc_id acc_id); + static void on_mwi_info(pjsua_acc_id acc_id, + pjsua_mwi_info *mwi_info); + + static void on_buddy_state(pjsua_buddy_id buddy_id); + // Call callbacks + static void on_call_state(pjsua_call_id call_id, pjsip_event *e); + static void on_call_tsx_state(pjsua_call_id call_id, + pjsip_transaction *tsx, + pjsip_event *e); + static void on_call_media_state(pjsua_call_id call_id); + static void on_call_sdp_created(pjsua_call_id call_id, + pjmedia_sdp_session *sdp, + pj_pool_t *pool, + const pjmedia_sdp_session *rem_sdp); + static void on_stream_created(pjsua_call_id call_id, + pjmedia_stream *strm, + unsigned stream_idx, + pjmedia_port **p_port); + static void on_stream_destroyed(pjsua_call_id call_id, + pjmedia_stream *strm, + unsigned stream_idx); + static void on_dtmf_digit(pjsua_call_id call_id, int digit); + static void on_call_transfer_request(pjsua_call_id call_id, + const pj_str_t *dst, + pjsip_status_code *code); + static void on_call_transfer_request2(pjsua_call_id call_id, + const pj_str_t *dst, + pjsip_status_code *code, + pjsua_call_setting *opt); + static void on_call_transfer_status(pjsua_call_id call_id, + int st_code, + const pj_str_t *st_text, + pj_bool_t final, + pj_bool_t *p_cont); + static void on_call_replace_request(pjsua_call_id call_id, + pjsip_rx_data *rdata, + int *st_code, + pj_str_t *st_text); + static void on_call_replace_request2(pjsua_call_id call_id, + pjsip_rx_data *rdata, + int *st_code, + pj_str_t *st_text, + pjsua_call_setting *opt); + static void on_call_replaced(pjsua_call_id old_call_id, + pjsua_call_id new_call_id); + static void on_call_rx_offer(pjsua_call_id call_id, + const pjmedia_sdp_session *offer, + void *reserved, + pjsip_status_code *code, + pjsua_call_setting *opt); + static pjsip_redirect_op on_call_redirected(pjsua_call_id call_id, + const pjsip_uri *target, + const pjsip_event *e); + static pj_status_t + on_call_media_transport_state(pjsua_call_id call_id, + const pjsua_med_tp_state_info *info); + static void on_call_media_event(pjsua_call_id call_id, + unsigned med_idx, + pjmedia_event *event); + static pjmedia_transport* + on_create_media_transport(pjsua_call_id call_id, + unsigned media_idx, + pjmedia_transport *base_tp, + unsigned flags); + +private: + void clearCodecInfoList(); + +}; + + + +/** + * @} PJSUA2_UA + */ + +} +/* End pj namespace */ + + +#endif /* __PJSUA2_UA_HPP__ */ + |