diff --git a/sflphone-gtk/src/dbus.c b/sflphone-gtk/src/dbus.c index 4332d09df0d291e09bc2c579e9996e4943892c86..4debf578405a73919aa8ddc0b0966d53e34252ea 100644 --- a/sflphone-gtk/src/dbus.c +++ b/sflphone-gtk/src/dbus.c @@ -86,7 +86,7 @@ incoming_message_cb (DBusGProxy *proxy, const gchar* msg, void * foo ) { - g_print ("Messge %s! \n",msg); + g_print ("Message %s! \n",msg); } diff --git a/src/account.h b/src/account.h index 2f2c5123268e2e35ae0b8422dba592871dba2019..af0a20d7e425d344be641ec49c3b837c03845c73 100644 --- a/src/account.h +++ b/src/account.h @@ -27,38 +27,56 @@ class VoIPLink; +/** + * @file account.h + * @brief Interface to protocol account (SIPAccount, IAXAccount) + * It can be enable on loading or activate after. + * It contains account, configuration, VoIP Link and Calls (inside the VoIPLink) + */ + typedef std::string AccountID; + #define AccountNULL "" +/** Account type: SIP / IAX2 are supported */ #define CONFIG_ACCOUNT_TYPE "Account.type" +/** Tells if account is enable or not */ #define CONFIG_ACCOUNT_ENABLE "Account.enable" -//#define CONFIG_ACCOUNT_AUTO_REGISTER "Account.autoregister" +/** Account alias */ #define CONFIG_ACCOUNT_ALIAS "Account.alias" - +/** IAX paramater : full name */ #define IAX_FULL_NAME "IAX.fullName" +/** IAX paramater : host name */ #define IAX_HOST "IAX.host" +/** IAX paramater : user name */ #define IAX_USER "IAX.user" +/** IAX paramater : password */ #define IAX_PASS "IAX.pass" - +/** SIP parameter : full name */ #define SIP_FULL_NAME "SIP.fullName" +/** SIP parameter : user name */ #define SIP_USER_PART "SIP.userPart" +/** SIP parameter : authorization name */ #define SIP_AUTH_NAME "SIP.username" +/** SIP parameter : password */ #define SIP_PASSWORD "SIP.password" +/** SIP parameter : host name */ #define SIP_HOST_PART "SIP.hostPart" +/** SIP parameter : proxy address */ #define SIP_PROXY "SIP.proxy" +/** SIP parameter : stun server address */ #define SIP_STUN_SERVER "STUN.server" +/** SIP parameter : tells if stun is used or not */ #define SIP_USE_STUN "STUN.enable" +/** SIP parameter : stun port */ #define SIP_STUN_PORT "STUN.port" -/** - * Class account is an interface to protocol account (SIPAccount, IAXAccount) - * It can be enable on loading or activate after. - * It contains account, configuration, VoIP Link and Calls (inside the VoIPLink) - * @author Yan Morin - */ class Account{ public: Account(const AccountID& accountID); - + + /** + * Virtual destructor + */ virtual ~Account(); /** @@ -74,35 +92,32 @@ class Account{ /** * Get the voiplink pointer - * @return the pointer or 0 + * @return VoIPLink* the pointer or 0 */ inline VoIPLink* getVoIPLink() { return _link; } /** * Register the underlying VoIPLink. Launch the event listener. - * * This should update the getRegistrationState() return value. - * - * @return false is an error occurs */ virtual void registerVoIPLink() = 0; /** * Unregister the underlying VoIPLink. Stop the event listener. - * * This should update the getRegistrationState() return value. - * - * @return false is an error occurs */ virtual void unregisterVoIPLink() = 0; /** - * Tell if the account is enable or not. See doc for _enabled. + * Tell if the account is enable or not. + * @return true if enabled + * false otherwise */ bool isEnabled() { return _enabled; } /** - * Return registration state of underlying VoIPLink + * Get the registration state of the specified link + * @return RegistrationState The registration state of underlying VoIPLink */ VoIPLink::RegistrationState getRegistrationState() { return _link->getRegistrationState(); } @@ -136,9 +151,7 @@ protected: /** * Tells if the link is enabled, active. - * * This implies the link will be initialized on startup. - * * Modified by the configuration (key: ENABLED) */ bool _enabled; diff --git a/src/accountcreator.h b/src/accountcreator.h index 01215077c2ec20f9576bcbc42262b6e1f876509a..c91b3f7220567779cffa54505ce38209a19bbce6 100644 --- a/src/accountcreator.h +++ b/src/accountcreator.h @@ -25,8 +25,8 @@ class Account; /** - * AccountCreator create Protocol-specific Account - * @author Yan Morin <yan.morin@gmail.com> + * @file accountcreator.h + * @brief Create protocol-specific account */ class AccountCreator{ public: diff --git a/src/audio/audiodevice.h b/src/audio/audiodevice.h index fb29ebf276f4304556991ffcb21ef384c42c9328..acdfee46368c8f9d187a6d82556600ad4ef8dabb 100644 --- a/src/audio/audiodevice.h +++ b/src/audio/audiodevice.h @@ -26,7 +26,8 @@ #define AUDIODEVICERATE 8000 /** - * Container device for attribute storage + * @file audiodevice.c + * @brief Container device for attribute storage * Have almost only get/set method */ class AudioDevice { diff --git a/src/call.h b/src/call.h index fbac5779970d39c6347c85f38f0b639ab4c4fe84..63b2de4443d93d6a89350e1e7768f597dc1c6380 100644 --- a/src/call.h +++ b/src/call.h @@ -20,37 +20,39 @@ #ifndef CALL_H #define CALL_H -/* @file call.h - * @brief A call is the base class for protocol-based calls - */ #include <string> #include <cc++/thread.h> // for mutex #include "audio/codecDescriptor.h" +/* + * @file call.h + * @brief A call is the base class for protocol-based calls + */ + typedef std::string CallID; class Call{ -public: - /** - * This determines if the call originated from the local user (Outgoing) - * or from some remote peer (Incoming). - */ - enum CallType {Incoming, Outgoing}; - - /** - * Tell where we're at with the call. The call gets Connected when we know - * from the other end what happened with out call. A call can be 'Connected' - * even if the call state is Busy, Refused, or Error. - * - * Audio should be transmitted when ConnectionState = Connected AND - * CallState = Active. - */ - enum ConnectionState {Disconnected, Trying, Progressing, Ringing, Connected}; - - /** - * The Call State. - */ - enum CallState {Inactive, Active, Hold, Busy, Refused, Error}; + public: + /** + * This determines if the call originated from the local user (Outgoing) + * or from some remote peer (Incoming). + */ + enum CallType {Incoming, Outgoing}; + + /** + * Tell where we're at with the call. The call gets Connected when we know + * from the other end what happened with out call. A call can be 'Connected' + * even if the call state is Busy, Refused, or Error. + * + * Audio should be transmitted when ConnectionState = Connected AND + * CallState = Active. + */ + enum ConnectionState {Disconnected, Trying, Progressing, Ringing, Connected}; + + /** + * The Call State. + */ + enum CallState {Inactive, Active, Hold, Busy, Refused, Error}; /** * Constructor of a call @@ -72,96 +74,160 @@ public: * @param number peer number */ void setPeerNumber(const std::string& number) { _peerNumber = number; } + + /** + * Get the peer number (destination on outgoing) + * not protected by mutex (when created) + * @return std::string The peer number + */ const std::string& getPeerNumber() { return _peerNumber; } /** * Set the peer name (caller in ingoing) * not protected by mutex (when created) - * @param number peer number + * @param name The peer name */ void setPeerName(const std::string& name) { _peerName = name; } + + /** + * Get the peer name (caller in ingoing) + * not protected by mutex (when created) + * @return std::string The peer name + */ const std::string& getPeerName() { return _peerName; } /** * Tell if the call is incoming + * @return true if yes + * false otherwise */ bool isIncoming() { return (_type == Incoming) ? true : false; } /** * Set the connection state of the call (protected by mutex) + * @param state The connection state */ void setConnectionState(ConnectionState state); + /** - * get the connection state of the call (protected by mutex) + * Get the connection state of the call (protected by mutex) + * @return ConnectionState The connection state */ ConnectionState getConnectionState(); /** * Set the state of the call (protected by mutex) + * @param state The call state */ void setState(CallState state); + /** - * get the call state of the call (protected by mutex) + * Get the call state of the call (protected by mutex) + * @return CallState The call state */ CallState getState(); /** * Set the audio start boolean (protected by mutex) * @param start true if we start the audio + * false otherwise */ void setAudioStart(bool start); /** * Tell if the audio is started (protected by mutex) * @return true if it's already started + * false otherwise */ bool isAudioStarted(); // AUDIO - /** Set internal codec Map: initialization only, not protected */ + /** + * Set internal codec Map: initialization only, not protected + * @param map The codec map + */ void setCodecMap(const CodecDescriptor& map) { _codecMap = map; } + + /** + * Get internal codec Map: initialization only, not protected + * @return CodecDescriptor The codec map + */ CodecDescriptor& getCodecMap(); - /** Set my IP [not protected] */ + /** + * Set my IP [not protected] + * @param ip The local IP address + */ void setLocalIp(const std::string& ip) { _localIPAddress = ip; } - /** Set local audio port, as seen by me [not protected] */ + /** + * Set local audio port, as seen by me [not protected] + * @param port The local audio port + */ void setLocalAudioPort(unsigned int port) { _localAudioPort = port;} - /** Set the audio port that remote will see. */ + /** + * Set the audio port that remote will see. + * @param port The external audio port + */ void setLocalExternAudioPort(unsigned int port) { _localExternalAudioPort = port; } - /** Return the audio port seen by the remote side. */ + /** + * Return the audio port seen by the remote side. + * @return unsigned int The external audio port + */ unsigned int getLocalExternAudioPort() { return _localExternalAudioPort; } - /** Return my IP [mutex protected] */ + /** + * Return my IP [mutex protected] + * @return std::string The local IP + */ const std::string& getLocalIp(); - - /** Return port used locally (for my machine) [mutex protected] */ + + /** + * Return port used locally (for my machine) [mutex protected] + * @return unsigned int The local audio port + */ unsigned int getLocalAudioPort(); - - /** Return audio port at destination [mutex protected] */ + + /** + * Return audio port at destination [mutex protected] + * @return unsigned int The remote audio port + */ unsigned int getRemoteAudioPort(); - /** Return IP of destination [mutex protected] */ + /** + * Return IP of destination [mutex protected] + * @return const std:string The remote IP address + */ const std::string& getRemoteIp(); - /** Return audio codec [mutex protected] */ + /** + * Return audio codec [mutex protected] + * @return AudioCodecType The payload of the codec + */ AudioCodecType getAudioCodec(); - - -protected: + protected: /** Protect every attribute that can be changed by two threads */ ost::Mutex _callMutex; - /** Set remote's IP addr. [not protected] */ + /** + * Set remote's IP addr. [not protected] + * @param ip The remote IP address + */ void setRemoteIP(const std::string& ip) { _remoteIPAddress = ip; } - /** Set remote's audio port. [not protected] */ + /** + * Set remote's audio port. [not protected] + * @param port The remote audio port + */ void setRemoteAudioPort(unsigned int port) { _remoteAudioPort = port; } - /** Set the audio codec used. [not protected] */ + /** + * Set the audio codec used. [not protected] + * @param audioCodec The payload of the codec + */ void setAudioCodec(AudioCodecType audioCodec) { _audioCodec = audioCodec; } /** Codec Map */ @@ -190,7 +256,7 @@ protected: unsigned int _remoteAudioPort; -private: + private: /** Unique ID of the call */ CallID _id; diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h index 0bda986c4ba852695a61f79f14037a561defdd39..a038f85c4a9702ccfe444ec35e497fffb35bdd53 100644 --- a/src/dbus/configurationmanager-glue.h +++ b/src/dbus/configurationmanager-glue.h @@ -25,8 +25,6 @@ public: register_method(ConfigurationManager, addAccount, _addAccount_stub); register_method(ConfigurationManager, removeAccount, _removeAccount_stub); register_method(ConfigurationManager, getAccountList, _getAccountList_stub); - register_method(ConfigurationManager, getDefaultAccount, _getDefaultAccount_stub); - register_method(ConfigurationManager, setDefaultAccount, _setDefaultAccount_stub); register_method(ConfigurationManager, sendRegister, _sendRegister_stub); register_method(ConfigurationManager, getToneLocaleList, _getToneLocaleList_stub); register_method(ConfigurationManager, getVersion, _getVersion_stub); @@ -90,16 +88,6 @@ public: { "list", "as", false }, { 0, 0, 0 } }; - static ::DBus::IntrospectedArgument getDefaultAccount_args[] = - { - { "accountID", "s", false }, - { 0, 0, 0 } - }; - static ::DBus::IntrospectedArgument setDefaultAccount_args[] = - { - { "accountID", "s", true }, - { 0, 0, 0 } - }; static ::DBus::IntrospectedArgument sendRegister_args[] = { { "accountID", "s", true }, @@ -280,8 +268,6 @@ public: { "addAccount", addAccount_args }, { "removeAccount", removeAccount_args }, { "getAccountList", getAccountList_args }, - { "getDefaultAccount", getDefaultAccount_args }, - { "setDefaultAccount", setDefaultAccount_args }, { "sendRegister", sendRegister_args }, { "getToneLocaleList", getToneLocaleList_args }, { "getVersion", getVersion_args }, @@ -353,8 +339,6 @@ public: virtual void addAccount( const std::map< ::DBus::String, ::DBus::String >& details ) = 0; virtual void removeAccount( const ::DBus::String& accoundID ) = 0; virtual std::vector< ::DBus::String > getAccountList( ) = 0; - virtual ::DBus::String getDefaultAccount( ) = 0; - virtual void setDefaultAccount( const ::DBus::String& accountID ) = 0; virtual void sendRegister( const ::DBus::String& accountID, const ::DBus::Int32& expire ) = 0; virtual std::vector< ::DBus::String > getToneLocaleList( ) = 0; virtual ::DBus::String getVersion( ) = 0; @@ -465,25 +449,6 @@ private: wi << argout1; return reply; } - ::DBus::Message _getDefaultAccount_stub( const ::DBus::CallMessage& call ) - { - ::DBus::MessageIter ri = call.reader(); - - ::DBus::String argout1 = getDefaultAccount(); - ::DBus::ReturnMessage reply(call); - ::DBus::MessageIter wi = reply.writer(); - wi << argout1; - return reply; - } - ::DBus::Message _setDefaultAccount_stub( const ::DBus::CallMessage& call ) - { - ::DBus::MessageIter ri = call.reader(); - - ::DBus::String argin1; ri >> argin1; - setDefaultAccount(argin1); - ::DBus::ReturnMessage reply(call); - return reply; - } ::DBus::Message _sendRegister_stub( const ::DBus::CallMessage& call ) { ::DBus::MessageIter ri = call.reader(); diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml index 93b17644bf6b1ca65cf33014ed78c0280bbb4c76..6ebaef5a3494ac99c2803d66dfa1ad9135b6a75c 100644 --- a/src/dbus/configurationmanager-introspec.xml +++ b/src/dbus/configurationmanager-introspec.xml @@ -25,14 +25,6 @@ <arg type="as" name="list" direction="out"/> </method> - <method name="getDefaultAccount"> - <arg type="s" name="accountID" direction="out"/> - </method> - - <method name="setDefaultAccount"> - <arg type="s" name="accountID" direction="in"/> - </method> - <method name="sendRegister"> <arg type="s" name="accountID" direction="in"/> <arg type="i" name="expire" direction="in"/> diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp index c09f62858bfaad80885e50377406d90b64aeeb42..d5bb6c5ef2fce4f7bd4b287870b4d35a7e0b34d4 100644 --- a/src/dbus/configurationmanager.cpp +++ b/src/dbus/configurationmanager.cpp @@ -217,24 +217,6 @@ ConfigurationManager::getRecordDeviceList( ) { _debug("ConfigurationManager::getRecordDeviceList received\n"); -} - - ::DBus::String -ConfigurationManager::getDefaultAccount( ) -{ - _debug("ConfigurationManager::getDefaultAccount received\n"); - return Manager::instance().getDefaultAccount(); -} - -/* - * used to set a default account - */ - void -ConfigurationManager::setDefaultAccount( const ::DBus::String& accountID ) -{ - _debug("ConfigurationManager::setDefaultAccount received\n"); - Manager::instance().setDefaultAccount(accountID); - } ::DBus::Int32 diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h index f5979b1b86705d517c350594e03ae2be1e4e676d..212374bfc50c6fa84dd7c48e52ce45622d44e1c9 100644 --- a/src/dbus/configurationmanager.h +++ b/src/dbus/configurationmanager.h @@ -44,8 +44,6 @@ public: void addAccount( const std::map< ::DBus::String, ::DBus::String >& details ); void removeAccount( const ::DBus::String& accoundID ); std::vector< ::DBus::String > getAccountList( ); - ::DBus::String getDefaultAccount( ); - void setDefaultAccount( const ::DBus::String& accountID ); void sendRegister( const ::DBus::String& accoundID , const ::DBus::Int32& expire ); std::vector< ::DBus::String > getCodecList( ); diff --git a/src/eventthread.h b/src/eventthread.h index 65daaf9003e2e95556463dbbf992faad206c57c7..21f43a897ac87fc9c639d7c9089acd98bff49a93 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -24,9 +24,12 @@ #include <cc++/thread.h> class VoIPLink; + /** - * General thread to listen events continuously + * @file eventthread.h + * @brief General thread to listen events continuously */ + class EventThread : public ost::Thread { public: /** diff --git a/src/global.h b/src/global.h index 0252b420c0de019ed38b8834a3d2aa86c49f31a0..4fe6ded002f067f7a10b8ca91888c56b412b0a58 100644 --- a/src/global.h +++ b/src/global.h @@ -61,62 +61,61 @@ typedef short int16; #define _debugAlsa(...) #endif -#define SFLPHONED_VERSION "0.8.2" +#define SFLPHONED_VERSION "0.8.2" /** Version number */ #define SFLPHONED_VERSIONNUM 0x000802 -#define PROGNAME "sflphoned" -#define PROGNAME_GLOBAL "sflphone" -#define PROGDIR "sflphone" -#define RINGDIR "ringtones" -#define CODECDIR "codecs" +#define PROGNAME "sflphoned" /** Binary name */ +#define PROGNAME_GLOBAL "sflphone" /** Program name */ +#define PROGDIR "sflphone" /** Program directory */ +#define RINGDIR "ringtones" /** Ringtones directory */ +#define CODECDIR "codecs" /** Codecs directory */ #define _(arg) arg #define MONO 1 #define CHANNELS 2 #define SIZEBUF 1024*1024 -#define ALSA_DFT_CARD_ID 0 - -#define PCM_HW "hw" -#define PCM_PLUGHW "plughw" -#define PCM_PULSE "pulse" -#define PCM_FRONT "plug:front" -#define PCM_DEFAULT "default" -#define PCM_DMIX "plug:dmix" -#define PCM_SURROUND40 "plug:surround40" -#define PCM_SURROUND41 "plug:surround41" -#define PCM_SURROUND50 "plug:surround50" -#define PCM_SURROUND51 "plug:surround51" -#define PCM_SURROUND71 "plug:surround71" -#define PCM_IEC958 "plug:iec958" - -#define SFL_CODEC_VALID_PREFIX "libcodec_" -#define SFL_CODEC_VALID_EXTEN ".so" -#define CURRENT_DIR "." -#define PARENT_DIR ".." - -#define SFL_PCM_BOTH 0x0021 -#define SFL_PCM_PLAYBACK 0x0022 -#define SFL_PCM_CAPTURE 0x0023 +#define ALSA_DFT_CARD_ID 0 /** Index of the default soundcard */ + +#define PCM_HW "hw" /** Alsa plugin hardware */ +#define PCM_PLUGHW "plughw" /** Alsa plugin */ +#define PCM_PULSE "pulse" /** Alsa plugin for pulse audio */ +#define PCM_FRONT "plug:front" /** Alsa plugin: front PCM */ +#define PCM_DEFAULT "default" /** Default ALSA plugin */ +#define PCM_DMIX "plug:dmix" /** Alsa plugin for software mixing */ +#define PCM_SURROUND40 "plug:surround40" /** Alsa plugin: surround40 */ +#define PCM_SURROUND41 "plug:surround41" /** Alsa plugin: surround41 */ +#define PCM_SURROUND50 "plug:surround50" /** Alsa plugin: surround50 */ +#define PCM_SURROUND51 "plug:surround51" /** Alsa plugin: surround51 */ +#define PCM_SURROUND71 "plug:surround71" /** Alsa plugin: surround71 */ + +#define SFL_CODEC_VALID_PREFIX "libcodec_" /** Valid prefix for codecs shared library */ +#define SFL_CODEC_VALID_EXTEN ".so" /** Valid extension for codecs shared library */ +#define CURRENT_DIR "." /** Current directory */ +#define PARENT_DIR ".." /** Parent directory */ + +#define SFL_PCM_BOTH 0x0021 /** To open both playback and capture devices */ +#define SFL_PCM_PLAYBACK 0x0022 /** To open playback device only */ +#define SFL_PCM_CAPTURE 0x0023 /** To open capture device only */ #ifdef USE_IAX -#define IAX2_ENABLED true +#define IAX2_ENABLED true /** IAX2 support */ #else -#define IAX2_ENABLED false +#define IAX2_ENABLED false /** IAX2 support */ #endif -#define GSM_STRING_DESCRIPTION "gsm" -#define SPEEX_STRING_DESCRIPTION "speex" -#define ILBC_STRING_DESCRIPTION "ilbc" -#define RINGTONE_ENABLED 1 -#define DISPLAY_DIALPAD 1 -#define START_HIDDEN 1 -#define WINDOW_POPUP 1 +#define GSM_STRING_DESCRIPTION "gsm" /** GSM codec string description */ +#define SPEEX_STRING_DESCRIPTION "speex" /** SPEEX codec string description */ +#define ILBC_STRING_DESCRIPTION "ilbc" /** Ilbc codec string description */ +#define RINGTONE_ENABLED 1 /** Custom ringtone enable or not */ +#define DISPLAY_DIALPAD 1 /** Display dialpad or not */ +#define START_HIDDEN 1 /** SFlphone starts hidden at start-up or not */ +#define WINDOW_POPUP 1 /** Popup mode */ // Error codes for error handling -#define NO_ERROR 0x0000 -#define ALSA_CAPTURE_DEVICE 0x0001 -#define ALSA_PLAYBACK_DEVICE 0x0010 -#define NETWORK_UNREACHABLE 0x0011 +#define NO_ERROR 0x0000 /** No error - Everything alright */ +#define ALSA_CAPTURE_DEVICE 0x0001 /** Error while opening capture device */ +#define ALSA_PLAYBACK_DEVICE 0x0010 /** Error while opening playback device */ +#define NETWORK_UNREACHABLE 0x0011 /** Network unreachable */ #endif // __GLOBAL_H__ diff --git a/src/iaxaccount.h b/src/iaxaccount.h index 6e6472395ebb8e49942f9556fd569a3fe8b7699f..2cdfb6232ad0dc338cdb708d69bfdbb7ed34b7f2 100644 --- a/src/iaxaccount.h +++ b/src/iaxaccount.h @@ -24,8 +24,8 @@ /** - * An IAX Account specify IAX specific functions and objects (IAXCall/IAXVoIPLink) - * @author Yan Morin <yan.morin@gmail.com> + * @file: iaxaccount.h + * @brief: an IAX Account specify IAX specific functions and objects (IAXCall/IAXVoIPLink) */ class IAXAccount : public Account { @@ -34,9 +34,19 @@ public: ~IAXAccount(); - /** Actually unuseful, since config loading is done in init() */ + /** + * Actually unuseful, since config loading is done in init() + */ void loadConfig(); + + /** + * Register an account + */ void registerVoIPLink(); + + /** + * Unregister an account + */ void unregisterVoIPLink(); private: diff --git a/src/iaxcall.h b/src/iaxcall.h index 2c6d612d867d8bfc6409e4a4b6108d90197a9089..ccfe8c41d5dd3e69b9ba9ef1089cf52c0b225a8f 100644 --- a/src/iaxcall.h +++ b/src/iaxcall.h @@ -25,42 +25,53 @@ #include <iax/frame.h> /** - * IAXCall are IAX implementation of a normal Call - * @author Yan Morin <yan.morin@gmail.com> + * @file: iaxcall.h + * @brief: IAXCall are IAX implementation of a normal Call */ + class IAXCall : public Call { public: + /** + * Constructor + * @param id The unique ID of the call + * @param type The type of the call + */ IAXCall(const CallID& id, Call::CallType type); + /** + * Destructor + */ ~IAXCall(); - /** Get the session pointer or NULL */ + /** + * @return iax_session* The session pointer or NULL + */ struct iax_session* getSession() { return _session; } - /** Set the session pointer + /** + * Set the session pointer * @param session the session pointer to assign */ void setSession(struct iax_session* session) { _session = session; } /** - * Set format (one single bit - * + * Set format (one single bit) * This function sets the _audioCodec variable with the correct * codec. + * @param format The format representing the codec */ void setFormat(int format); /** * Get format for the voice codec used - * - * Bitmask for codecs defined in iax/frame.h + * @return int Bitmask for codecs defined in iax/frame.h */ int getFormat() { return _format; } /** - * Get the bitwise list of supported formats + * @return int The bitwise list of supported formats */ int getSupportedFormat(); @@ -75,7 +86,7 @@ public: * in this call context. * * @param needles The format(s) (bitwise) you are looking for to match - * @return The matching format, thus 0 if none matches + * @return int The matching format, thus 0 if none matches */ int getFirstMatchingFormat(int needles); diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp index 17607f4889c74e8652987ebf42e7589d7b43e930..510ba7642f75e2b19daadb9a2376078d5ef5fefe 100644 --- a/src/iaxvoiplink.cpp +++ b/src/iaxvoiplink.cpp @@ -363,11 +363,9 @@ IAXVoIPLink::sendRegister() bool result = false; if (_host.empty()) { - Manager::instance().displayConfigError("Fill host field for IAX Account"); return false; } if (_user.empty()) { - Manager::instance().displayConfigError("Fill user field for IAX Account"); return false; } @@ -656,7 +654,6 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call) } call->setConnectionState(Call::Connected); call->setState(Call::Error); - Manager::instance().displayErrorText(id, "Failure"); Manager::instance().callFailure(id); removeCall(id); break; @@ -690,7 +687,6 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call) case IAX_EVENT_BUSY: call->setConnectionState(Call::Connected); call->setState(Call::Busy); - Manager::instance().displayErrorText(id, "Busy"); Manager::instance().callBusy(id); removeCall(id); break; diff --git a/src/iaxvoiplink.h b/src/iaxvoiplink.h index 05f1a08735d3fe9350bd0a426f63f98db690ede2..9e2acd6c8d4948ee1533ef217ecfe22c3b3a736c 100644 --- a/src/iaxvoiplink.h +++ b/src/iaxvoiplink.h @@ -2,6 +2,7 @@ * Copyright (C) 2006-2007 Savoir-Faire Linux inc. * Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com> * Author: Yan Morin <yan.morin@savoirfairelinux.com> + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.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 @@ -27,189 +28,285 @@ #include "audio/codecDescriptor.h" -/** @todo Remove this fstream/iostream stuff */ -#include <fstream> // fstream + iostream for _fstream debugging... -#include <iostream> - - class EventThread; class IAXCall; class AudioCodec; class AudioLayer; - /** - * VoIPLink contains a thread that listen to external events + * @file iaxvoiplink.h + * @brief VoIPLink contains a thread that listen to external events * and contains IAX Call related functions - * @author Yan Morin <yan.morin@gmail.com> */ + class IAXVoIPLink : public VoIPLink { -public: + public: + + /** + * Constructor + * @param accountID The account containing the voip link + */ IAXVoIPLink(const AccountID& accountID); + /** + * Destructor + */ ~IAXVoIPLink(); - void getEvent(void); - bool init (void); - bool checkNetwork (void) { return false; } - void terminate (void); - - /** - * Send out registration - * - * @return The new registration state (are we registered ?) - */ - bool sendRegister (void); - - /** - * Destroy registration session - * - * @todo Send an IAX_COMMAND_REGREL to force unregistration upstream. - * Urgency: low - * - * @return bool If we're registered upstream - */ - bool sendUnregister (void); - - Call* newOutgoingCall(const CallID& id, const std::string& toUrl); - bool answer(const CallID& id); - - bool hangup(const CallID& id); - bool cancel(const CallID& id) { return false; } - bool onhold(const CallID& id); - bool offhold(const CallID& id); - bool transfer(const CallID& id, const std::string& to); - bool refuse (const CallID& id); - bool carryingDTMFdigits(const CallID& id, char code); - bool sendMessage(const std::string& to, const std::string& body) { return false; } - bool isContactPresenceSupported() { return false; } - -public: // iaxvoiplink only - void setHost(const std::string& host) { _host = host; } - void setUser(const std::string& user) { _user = user; } - void setPass(const std::string& pass) { _pass = pass; } - -private: - /** - * Get IAX Call from an id - * @param id CallId - * @return IAXCall pointer or 0 - */ - IAXCall* getIAXCall(const CallID& id); - - /** - * Delete every call - */ - void terminateIAXCall(); - - /** - * Find a iaxcall by iax session number - * @param session an iax_session valid pointer - * @return iaxcall or 0 if not found - */ - IAXCall* iaxFindCallBySession(struct iax_session* session); - - /** - * Handle IAX Event for a call - * @param event An iax_event pointer - * @param call An IAXCall pointer - */ - void iaxHandleCallEvent(iax_event* event, IAXCall* call); - - /** - * Handle the VOICE events specifically - * @param event The iax_event containing the IAX_EVENT_VOICE - * @param call The associated IAXCall - */ - void iaxHandleVoiceEvent(iax_event* event, IAXCall* call); - - /** - * Handle IAX Registration Reply event - * @param event An iax_event pointer - */ - void iaxHandleRegReply(iax_event* event); - - /** - * Handle IAX pre-call setup-related events - * @param event An iax_event pointer - */ - void iaxHandlePrecallEvent(iax_event* event); - - /** - * Work out the audio data from Microphone to IAX2 channel - */ - void sendAudioFromMic(void); - - /** - * Send an outgoing call invite to iax - * @param call An IAXCall pointer - */ - bool iaxOutgoingInvite(IAXCall* call); - - - /** - * Convert CodecMap to IAX format using IAX constants - * @return `format` ready to go into iax_* calls - */ - int iaxCodecMapToFormat(IAXCall* call); - - /** Threading object */ - EventThread* _evThread; - - /** registration session : 0 if not register */ - struct iax_session* _regSession; - - /** IAX Host */ - std::string _host; - - /** IAX User */ - std::string _user; - - /** IAX Password */ - std::string _pass; - - /** IAX full name */ - std::string _fullName; - - /** Timestamp of when we should refresh the registration up with - * the registrar. Values can be: EPOCH timestamp, 0 if we want no registration, 1 - * to force a registration. */ - int _nextRefreshStamp; - - /** Mutex for iax_ calls, since we're the only one dealing with the incorporated - * iax_stuff inside this class. */ - ost::Mutex _mutexIAX; - - /** Connection to audio card/device */ - AudioLayer* audiolayer; - - /** When we receive data, we decode it inside this buffer */ - int16* _receiveDataDecoded; - /** When we send data, we encode it inside this buffer*/ - unsigned char* _sendDataEncoded; - - /** After that we send the data inside this buffer if there is a format conversion or rate conversion. */ - /* Also use for getting mic-ringbuffer data */ - SFLDataFormat* _dataAudioLayer; - - /** Buffer for 8000hz samples in conversion */ - float32* _floatBuffer8000; - /** Buffer for 48000hz samples in conversion */ - float32* _floatBuffer48000; - - /** Buffer for 8000hz samples for mic conversion */ - int16* _intBuffer8000; - - /** libsamplerate converter for incoming voice */ - SRC_STATE* _src_state_spkr; - - /** libsamplerate converter for outgoing voice */ - SRC_STATE* _src_state_mic; - - /** libsamplerate error */ - int _src_err; + /** + * Listen to events sent by the call manager ( asterisk, etc .. ) + */ + void getEvent(void); + + /** + * Init the voip link + * @return true if successful + * false otherwise + */ + bool init (void); + + /** + * Check if a local IP can be found + * @return true if pingable + * false otherwise + */ + bool checkNetwork (void) { return false; } + + /** + * Terminate a voip link by clearing the call list + */ + void terminate (void); + + /** + * Send out registration + * @return bool The new registration state (are we registered ?) + */ + bool sendRegister (void); + + /** + * Destroy registration session + * @todo Send an IAX_COMMAND_REGREL to force unregistration upstream. + * Urgency: low + * @return bool true if we're registered upstream + * false otherwise + */ + bool sendUnregister (void); + + /** + * Create a new outgoing call + * @param id The ID of the call + * @param toUrl The address to call + * @return Call* A pointer on the call + */ + Call* newOutgoingCall(const CallID& id, const std::string& toUrl); + + /** + * Answer a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool answer(const CallID& id); + + /** + * Hangup a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool hangup(const CallID& id); + + /** + * Cancel a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool cancel(const CallID& id) { return false; } + + /** + * Put a call on hold + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool onhold(const CallID& id); + + /** + * Put a call off hold + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool offhold(const CallID& id); + + /** + * Transfer a call + * @param id The ID of the call + * @param to The recipient of the transfer + * @return bool true on success + * false otherwise + */ + bool transfer(const CallID& id, const std::string& to); + + /** + * Refuse a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool refuse (const CallID& id); + + /** + * Send DTMF + * @param id The ID of the call + * @param code The code of the DTMF + * @return bool true on success + * false otherwise + */ + bool carryingDTMFdigits(const CallID& id, char code); + + bool sendMessage(const std::string& to, const std::string& body) { return false; } + + bool isContactPresenceSupported() { return false; } + + public: // iaxvoiplink only + /** + * @param host Set the host name + */ + void setHost(const std::string& host) { _host = host; } + + /** + * @param user Set the user name + */ + void setUser(const std::string& user) { _user = user; } + + /** + * @param pass Set the password + */ + void setPass(const std::string& pass) { _pass = pass; } + + private: + /** + * Get IAX Call from an id + * @param id CallId + * @return IAXCall pointer or 0 + */ + IAXCall* getIAXCall(const CallID& id); + + /** + * Delete every call + */ + void terminateIAXCall(); + + /** + * Find a iaxcall by iax session number + * @param session an iax_session valid pointer + * @return iaxcall or 0 if not found + */ + IAXCall* iaxFindCallBySession(struct iax_session* session); + + /** + * Handle IAX Event for a call + * @param event An iax_event pointer + * @param call An IAXCall pointer + */ + void iaxHandleCallEvent(iax_event* event, IAXCall* call); + + /** + * Handle the VOICE events specifically + * @param event The iax_event containing the IAX_EVENT_VOICE + * @param call The associated IAXCall + */ + void iaxHandleVoiceEvent(iax_event* event, IAXCall* call); + + /** + * Handle IAX Registration Reply event + * @param event An iax_event pointer + */ + void iaxHandleRegReply(iax_event* event); + + /** + * Handle IAX pre-call setup-related events + * @param event An iax_event pointer + */ + void iaxHandlePrecallEvent(iax_event* event); + + /** + * Work out the audio data from Microphone to IAX2 channel + */ + void sendAudioFromMic(void); + + /** + * Send an outgoing call invite to iax + * @param call An IAXCall pointer + */ + bool iaxOutgoingInvite(IAXCall* call); + + + /** + * Convert CodecMap to IAX format using IAX constants + * @return `format` ready to go into iax_* calls + */ + int iaxCodecMapToFormat(IAXCall* call); + + /** Threading object */ + EventThread* _evThread; + + /** registration session : 0 if not register */ + struct iax_session* _regSession; + + /** IAX Host */ + std::string _host; + + /** IAX User */ + std::string _user; + + /** IAX Password */ + std::string _pass; + + /** IAX full name */ + std::string _fullName; + + /** Timestamp of when we should refresh the registration up with + * the registrar. Values can be: EPOCH timestamp, 0 if we want no registration, 1 + * to force a registration. */ + int _nextRefreshStamp; + + /** Mutex for iax_ calls, since we're the only one dealing with the incorporated + * iax_stuff inside this class. */ + ost::Mutex _mutexIAX; + + /** Connection to audio card/device */ + AudioLayer* audiolayer; + + /** When we receive data, we decode it inside this buffer */ + int16* _receiveDataDecoded; + /** When we send data, we encode it inside this buffer*/ + unsigned char* _sendDataEncoded; + + /** After that we send the data inside this buffer if there is a format conversion or rate conversion. */ + /* Also use for getting mic-ringbuffer data */ + SFLDataFormat* _dataAudioLayer; + + /** Buffer for 8000hz samples in conversion */ + float32* _floatBuffer8000; + /** Buffer for 48000hz samples in conversion */ + float32* _floatBuffer48000; + + /** Buffer for 8000hz samples for mic conversion */ + int16* _intBuffer8000; + + /** libsamplerate converter for incoming voice */ + SRC_STATE* _src_state_spkr; + + /** libsamplerate converter for outgoing voice */ + SRC_STATE* _src_state_mic; + + /** libsamplerate error */ + int _src_err; }; diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 725e38b3b827016469e8ad98447fe879708aafd6..a112f240c90061c638cd23a32ee1b02d2824d779 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -77,7 +77,6 @@ ManagerImpl::ManagerImpl (void) _dtmfKey = 0; _spkr_volume = 0; // Initialize after by init() -> initVolume() _mic_volume = 0; // Initialize after by init() -> initVolume() - _mic_volume_before_mute = 0; // Call _nbIncomingWaitingCall=0; @@ -229,10 +228,6 @@ ManagerImpl::outgoingCall(const std::string& accountid, const CallID& id, const ManagerImpl::answerCall(const CallID& id) { stopTone(false); - /*if (hasCurrentCall()) - { - onHoldCall(getCurrentCallId()); - }*/ AccountID accountid = getAccountFromCall( id ); if (accountid == AccountNULL) { _debug("Answering Call: Call doesn't exists\n"); @@ -245,9 +240,6 @@ ManagerImpl::answerCall(const CallID& id) return false; } - //Place current call on hold if it isn't - - // if it was waiting, it's waiting no more if (_dbus) _dbus->getCallManager()->callStateChanged(id, "CURRENT"); removeWaitingCall(id); @@ -283,7 +275,6 @@ ManagerImpl::hangupCall(const CallID& id) removeCallAccount(id); switchCall(""); - return returnValue; } @@ -351,13 +342,7 @@ ManagerImpl::offHoldCall(const CallID& id) bool returnValue = getAccountLink(accountid)->offhold(id); if (_dbus) _dbus->getCallManager()->callStateChanged(id, "UNHOLD"); switchCall(id); - if (returnValue) { - try { - //getAudioDriver()->startStream(); - } catch(...) { - _debugException("! Manager Off hold could not start audio stream"); - } - } + return returnValue; } @@ -376,26 +361,9 @@ ManagerImpl::transferCall(const CallID& id, const std::string& to) removeCallAccount(id); if (_dbus) _dbus->getCallManager()->callStateChanged(id, "HUNGUP"); switchCall(""); - - return returnValue; } -//THREAD=Main -void -ManagerImpl::mute() { - _mic_volume_before_mute = _mic_volume; - setMicVolume(0); -} - -//THREAD=Main -void -ManagerImpl::unmute() { - if ( _mic_volume == 0 ) { - setMicVolume(_mic_volume_before_mute); - } -} - //THREAD=Main : Call:Incoming bool ManagerImpl::refuseCall (const CallID& id) @@ -455,46 +423,6 @@ ManagerImpl::initRegisterAccounts() return true; } -//THREAD=Main -// Currently unused - bool -ManagerImpl::registerAccount(const AccountID& accountId) -{ - _debug("Register one VoIP Link\n"); - - // right now, we don't support two SIP account - // so we close everything before registring a new account - Account* account = getAccount(accountId); - if (account != 0) { - AccountMap::iterator iter = _accountMap.begin(); - while ( iter != _accountMap.end() ) { - if ( iter->second ) { - iter->second->unregisterVoIPLink(); - } - iter++; - } - // NOW - account->registerVoIPLink(); - account->loadContacts(); - account->publishPresence(PRESENCE_ONLINE); - account->subscribeContactsPresence(); - } - return true; -} - -//THREAD=Main -// Currently unused - bool -ManagerImpl::unregisterAccount(const AccountID& accountId) -{ - _debug("Unregister one VoIP Link\n"); - - if (accountExists( accountId ) ) { - getAccount(accountId)->unregisterVoIPLink(); - } - return true; -} - //THREAD=Main bool ManagerImpl::sendDtmf(const CallID& id, char code) @@ -567,15 +495,6 @@ ManagerImpl::playDtmf(char code, bool isTalking) // put the size in bytes... // so size * 1 channel (mono) * sizeof (bytes for the data) audiolayer->playSamples(_buf, size * sizeof(SFLDataFormat), isTalking); - //audiolayer->putUrgent(_buf, size * sizeof(SFLDataFormat)); - - // We activate the stream if it's not active yet. - //if (!audiolayer->isStreamActive()) { - //audiolayer->startStream(); - //} else { - //_debugAlsa("send dtmf - sleep\n"); - //audiolayer->sleep(pulselen); // in milliseconds - //} } returnValue = true; @@ -617,8 +536,6 @@ ManagerImpl::isWaitingCall(const CallID& id) { return true; } - - /////////////////////////////////////////////////////////////////////////////// // Management of event peer IP-phone //////////////////////////////////////////////////////////////////////////////// @@ -730,53 +647,6 @@ ManagerImpl::callFailure(const CallID& id) } -//THREAD=VoIP - void -ManagerImpl::displayTextMessage(const CallID& id, const std::string& message) -{ - /*if(_gui) { - _gui->displayTextMessage(id, message); - }*/ -} - -//THREAD=VoIP - void -ManagerImpl::displayErrorText(const CallID& id, const std::string& message) -{ - /*if(_gui) { - _gui->displayErrorText(id, message); - } else { - std::cerr << message << std::endl; - }*/ -} - -//THREAD=VoIP - void -ManagerImpl::displayError (const std::string& error) -{ - /*if(_gui) { - _gui->displayError(error); - }*/ -} - -//THREAD=VoIP - void -ManagerImpl::displayStatus(const std::string& status) -{ - /*if(_gui) { - _gui->displayStatus(status); - }*/ -} - -//THREAD=VoIP - void -ManagerImpl::displayConfigError (const std::string& message) -{ - /*if(_gui) { - _gui->displayConfigError(message); - }*/ -} - //THREAD=VoIP void ManagerImpl::startVoiceMessageNotification(const AccountID& accountId, const std::string& nb_msg) @@ -784,14 +654,6 @@ ManagerImpl::startVoiceMessageNotification(const AccountID& accountId, const std if (_dbus) _dbus->getCallManager()->voiceMailNotify(accountId, atoi(nb_msg.c_str()) ); } -//THREAD=VoIP - void -ManagerImpl::stopVoiceMessageNotification(const AccountID& accountId) -{ - // TODO : do not notify when no messages - //if (_dbus) _dbus->getCallManager()->voiceMailNotify(accountId, 0 ); -} - //THREAD=VoIP void ManagerImpl::registrationSucceed(const AccountID& accountid) @@ -924,7 +786,6 @@ ManagerImpl::ringback () { void ManagerImpl::ringtone() { - // int hasToPlayTone = getConfigInt(SIGNALISATION, PLAY_TONES); if( isRingtoneEnabled() ) { std::string ringchoice = getConfigString(AUDIO, RING_CHOICE); @@ -983,11 +844,6 @@ ManagerImpl::getTelephoneFile() } } - -/** - * Use Urgent Buffer - * By AudioRTP thread - */ void ManagerImpl::notificationIncomingCall(void) { @@ -1169,7 +1025,7 @@ ManagerImpl::retrieveActiveCodecs() } void -ManagerImpl::setActiveCodecList(const std::vector<std::string>& list) +ManagerImpl::setActiveCodecList(const std::vector< ::DBus::String >& list) { _debug("Set active codecs list\n"); _codecDescriptorMap.saveActiveCodecs(list); @@ -1491,7 +1347,7 @@ ManagerImpl::popupMode( void ) } void -ManagerImpl::notifyErrClient( const int& errCode ) +ManagerImpl::notifyErrClient( const ::DBus::Int32& errCode ) { if( _dbus ){ _debug("NOTIFY ERR NUMBER %i\n" , errCode); @@ -1680,20 +1536,6 @@ ManagerImpl::detachZeroconfEvents(Pattern::Observer& observer) return returnValue; } -/** - * Main Thread - * - * @todo When is this called ? Why this name 'getEvents' ? - */ -/** - * DEPRECATED - bool - ManagerImpl::getEvents() { - initRegisterAccounts(); - return true; - } - */ - // TODO: rewrite this /** * Main Thread @@ -1746,7 +1588,6 @@ ManagerImpl::getCallStatus(const std::string& sequenceId) tk.push_back(iter->second); tk.push_back(destination); tk.push_back(status); - //_gui->sendCallMessage(code, sequenceId, iter->first, tk); tk.clear(); iter++; @@ -1755,23 +1596,6 @@ ManagerImpl::getCallStatus(const std::string& sequenceId) return true; } -//THREAD=Main - bool -ManagerImpl::getConfigAll(const std::string& sequenceId) -{ - bool returnValue = false; - Conf::ConfigTreeIterator iter = _config.createIterator(); - TokenList tk = iter.begin(); - if (tk.size()) { - returnValue = true; - } - while (tk.size()) { - //_gui->sendMessage("100", sequenceId, tk); - tk = iter.next(); - } - return returnValue; -} - //THREAD=Main bool ManagerImpl::getConfig(const std::string& section, const std::string& name, TokenList& arg) @@ -1821,99 +1645,6 @@ ManagerImpl::setConfig(const std::string& section, const std::string& name, int return _config.setConfigTreeItem(section, name, valueStream.str()); } -//THREAD=Main - bool -ManagerImpl::getAudioDeviceList(const std::string& sequenceId, int ioDeviceMask) -{ - AudioLayer* audiolayer = getAudioDriver(); - if (audiolayer == 0) { return false; } - - bool returnValue = false; - - // TODO: test when there is an error on initializing... - TokenList tk; - AudioDevice* device = 0; - int nbDevice = audiolayer->getDeviceCount(); - /* - for (int index = 0; index < nbDevice; index++ ) { - device = audiolayer->getAudioDeviceInfo(index, ioDeviceMask); - if (device != 0) { - tk.clear(); - std::ostringstream str; str << index; tk.push_back(str.str()); - tk.push_back(device->getName()); - tk.push_back(device->getApiName()); - std::ostringstream rate; rate << (int)(device->getRate()); tk.push_back(rate.str()); - //_gui->sendMessage("100", sequenceId, tk); - - // don't forget to delete it after - delete device; device = 0; - } - }*/ - returnValue = true; - - std::ostringstream rate; - rate << "VARIABLE"; - tk.clear(); - tk.push_back(rate.str()); - //_gui->sendMessage("101", sequenceId, tk); - - return returnValue; -} - -//THREAD=Main - bool -ManagerImpl::getCountryTones(const std::string& sequenceId) -{ - // see ToneGenerator for the list... - sendCountryTone(sequenceId, 1, "North America"); - sendCountryTone(sequenceId, 2, "France"); - sendCountryTone(sequenceId, 3, "Australia"); - sendCountryTone(sequenceId, 4, "United Kingdom"); - sendCountryTone(sequenceId, 5, "Spain"); - sendCountryTone(sequenceId, 6, "Italy"); - sendCountryTone(sequenceId, 7, "Japan"); - - return true; -} - -//THREAD=Main -void -ManagerImpl::sendCountryTone(const std::string& sequenceId, int index, const std::string& name) { - TokenList tk; - std::ostringstream str; str << index; tk.push_back(str.str()); - tk.push_back(name); - //_gui->sendMessage("100", sequenceId, tk); -} - -//THREAD=Main -bool -ManagerImpl::getDirListing(const std::string& sequenceId, const std::string& path, int *nbFile) { - TokenList tk; - try { - ost::Dir dir(path.c_str()); - const char *cFileName = 0; - std::string fileName; - std::string filePathName; - while ( (cFileName=dir++) != 0 ) { - fileName = cFileName; - filePathName = path + DIR_SEPARATOR_STR + cFileName; - if (fileName.length() && fileName[0]!='.' && !ost::isDir(filePathName.c_str())) { - tk.clear(); - std::ostringstream str; - str << (*nbFile); - tk.push_back(str.str()); - tk.push_back(filePathName); - //_gui->sendMessage("100", sequenceId, tk); - (*nbFile)++; - } - } - return true; - } catch (...) { - // error to open file dir - return false; - } -} - std::vector< std::string > ManagerImpl::getAccountList() { @@ -1932,8 +1663,6 @@ ManagerImpl::getAccountList() return v; } - - std::map< std::string, std::string > ManagerImpl::getAccountDetails(const AccountID& accountID) { @@ -1949,13 +1678,6 @@ ManagerImpl::getAccountDetails(const AccountID& accountID) getConfigString(accountID, CONFIG_ACCOUNT_ALIAS) ) ); - /*a.insert( - std::pair<std::string, std::string>( - CONFIG_ACCOUNT_AUTO_REGISTER, - getConfigString(accountID, CONFIG_ACCOUNT_AUTO_REGISTER)== "1" ? "TRUE": "FALSE" - ) - );*/ - _debug("Get account details: %s\n" , getConfigString(accountID, CONFIG_ACCOUNT_ENABLE).c_str()); a.insert( std::pair<std::string, std::string>( CONFIG_ACCOUNT_ENABLE, @@ -2112,18 +1834,11 @@ ManagerImpl::setAccountDetails( const ::DBus::String& accountID, if (_dbus) _dbus->getConfigurationManager()->accountsChanged(); } -/* - * register if it was just enabled, and we hadn't registered - * unregister if it was enabled/registered, and we want it closed - * unregister <=> expire = 0 ( FALSE ) - * register <=> expire = 1 ( TRUE ) - */ void ManagerImpl::sendRegister( const ::DBus::String& accountID , bool expire ) { // Update the active field setConfig( accountID, CONFIG_ACCOUNT_ENABLE, expire ); - Account* acc = getAccount(accountID); acc->loadConfig(); @@ -2189,90 +1904,6 @@ ManagerImpl::removeAccount(const AccountID& accountID) if (_dbus) _dbus->getConfigurationManager()->accountsChanged(); } - std::string -ManagerImpl::getDefaultAccount() -{ - - std::string id; - id = getConfigString(PREFERENCES, "DefaultAccount"); - _debug("Default Account = %s\n",id.c_str()); - return id; -} - - void -ManagerImpl::setDefaultAccount(const AccountID& accountID) -{ - // we write into the Preferences section the field Default - setConfig("Preferences", "DefaultAccount", accountID); -} - - - - -//THREAD=Main -/* - * Experimental... - */ -bool -ManagerImpl::setSwitch(const std::string& switchName, std::string& message) { - AudioLayer* audiolayer = 0; - if (switchName == "audiodriver" ) { - // hangup all call here - audiolayer = getAudioDriver(); - - int oldSampleRate = 0; - if (audiolayer) { oldSampleRate = audiolayer->getSampleRate(); } - - selectAudioDriver(); - audiolayer = getAudioDriver(); - - if (audiolayer) { - int error = audiolayer->getErrorMessage(); - int newSampleRate = audiolayer->getSampleRate(); - - if (error == -1) { - message = error; - return false; - } - - if (newSampleRate != oldSampleRate) { - _toneMutex.enterMutex(); - - _debug("Unload Telephone Tone\n"); - delete _telephoneTone; _telephoneTone = NULL; - _debug("Unload DTMF Key\n"); - delete _dtmfKey; _dtmfKey = NULL; - - _debug("Load Telephone Tone\n"); - std::string country = getConfigString(PREFERENCES, ZONE_TONE); - _telephoneTone = new TelephoneTone(country, newSampleRate); - - _debugInit("Loading DTMF key"); - _dtmfKey = new DTMF(newSampleRate); - - _toneMutex.leaveMutex(); - } - - message = _("Change with success"); - playDtmf('9', true); - //getAudioDriver()->sleep(300); // in milliseconds - playDtmf('1', true); - //getAudioDriver()->sleep(300); // in milliseconds - playDtmf('1', true); - return true; - } - } else if ( switchName == "echo" ) { - audiolayer = getAudioDriver(); - if (audiolayer) { - audiolayer->toggleEchoTesting(); - return true; - } - } - - - return false; -} - // ACCOUNT handling bool ManagerImpl::associateCallToAccount(const CallID& callID, const AccountID& accountID) @@ -2290,22 +1921,6 @@ ManagerImpl::associateCallToAccount(const CallID& callID, const AccountID& accou } } - AccountID - ManagerImpl::getAccountFromEvent( std::string authname ) -{ - AccountID id; - AccountMap::iterator iter = _accountMap.begin(); - while( iter != _accountMap.end() ){ - if( iter -> second != NULL ){ - id = iter -> first ; - if(getConfigString( id , SIP_AUTH_NAME ) == authname ) - return id; - } - } - return NULL; -} - - AccountID ManagerImpl::getAccountFromCall(const CallID& callID) { @@ -2353,7 +1968,6 @@ ManagerImpl::loadAccountMap() std::string accountType; Account* tmpAccount; - // iter = std::string TokenList::iterator iter = sections.begin(); while(iter != sections.end()) { // Check if it starts with "Account:" (SIP and IAX pour le moment) @@ -2384,37 +1998,6 @@ ManagerImpl::loadAccountMap() iter++; } - - /* - // SIP Loading X account... - short nbAccountSIP = ACCOUNT_SIP_COUNT_DEFAULT; - for (short iAccountSIP = 0; iAccountSIP<nbAccountSIP; iAccountSIP++) { - std::ostringstream accountName; - accountName << "SIP" << iAccountSIP; - - tmpAccount = AccountCreator::createAccount(AccountCreator::SIP_ACCOUNT, accountName.str()); - if (tmpAccount!=0) { - _debugMid(" %s", accountName.str().data()); - _accountMap[accountName.str()] = tmpAccount; - nbAccount++; - } - } - - // IAX Loading X account... - short nbAccountIAX = ACCOUNT_IAX_COUNT_DEFAULT; - for (short iAccountIAX = 0; iAccountIAX<nbAccountIAX; iAccountIAX++) { - std::ostringstream accountName; - accountName << "IAX" << iAccountIAX; - tmpAccount = AccountCreator::createAccount(AccountCreator::IAX_ACCOUNT, accountName.str()); - if (tmpAccount!=0) { - _debugMid(" %s", accountName.str().data()); - _accountMap[accountName.str()] = tmpAccount; - nbAccount++; - } - } - _debugEnd("\n"); - */ - return nbAccount; } diff --git a/src/managerimpl.h b/src/managerimpl.h index 378df590872648b926d5f5b91d0294b0d1c371a7..d2c2bb84b451a8bf80501d20e07622c2137f21c5 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -23,8 +23,6 @@ #ifndef __MANAGER_H__ #define __MANAGER_H__ -//#define TEST - #include <string> #include <vector> #include <set> @@ -44,8 +42,6 @@ #include "audio/dtmf.h" #include "audio/codecDescriptor.h" - - class AudioLayer; class CodecDescriptor; class GuiFramework; @@ -56,677 +52,893 @@ class VoIPLink; class DNSService; #endif -/** - * Define a type for a AccountMap container - */ +/** Define a type for a AccountMap container */ typedef std::map<AccountID, Account*> AccountMap; - -/** - * Define a type for a CallID to AccountID Map inside ManagerImpl - */ + +/** Define a type for a CallID to AccountID Map inside ManagerImpl */ typedef std::map<CallID, AccountID> CallAccountMap; -/** - * Define a type for CallID vector (waiting list, incoming not answered) - */ +/** Define a type for CallID vector (waiting list, incoming not answered) */ typedef std::set<CallID> CallIDSet; -/** - * To send multiple string - */ +/** To send multiple string */ typedef std::list<std::string> TokenList; -/** - * Manager (controller) of sflphone daemon - */ +/** Manager (controller) of sflphone daemon */ class ManagerImpl { -public: - ManagerImpl (void); - ~ManagerImpl (void); - - /** - * Initialisation of thread (sound) and map. - * - * Init a new VoIPLink, audio codec and audio driver - */ - void init (void); - - /** - * Terminate all thread (sound, link) and unload AccountMap - */ - void terminate (void); - - /** - * Set user interface manaager. - * @param man The DBUS interface implementation - */ - void setDBusManager (DBusManagerImpl* man) { _dbus = man; } - - /** - * Accessor to audiodriver. - * - * it's multi-thread and use mutex internally - */ - AudioLayer* getAudioDriver(void) const { return _audiodriver; } - - /** - * Get a descriptor map of codec available - */ - CodecDescriptor& getCodecDescriptorMap(void) {return _codecDescriptorMap;} - - /** - * Functions which occur with a user's action - */ - bool outgoingCall(const AccountID& accountId, const CallID& id, const std::string& to); - bool answerCall(const CallID& id); - bool hangupCall(const CallID& id); - bool cancelCall(const CallID& id); - bool onHoldCall(const CallID& id); - bool offHoldCall(const CallID& id); - bool transferCall(const CallID& id, const std::string& to); - void mute(); - void unmute(); - bool refuseCall(const CallID& id); - - /** Save config to file */ - bool saveConfig (void); - - /** - * Send registration information (shake hands) for a specific AccountID - * - * @param accountId Account to register - * @return true if sendRegister was called without failure, else return false - */ - bool registerAccount(const AccountID& accountId); - - /** - * Send unregistration for a specific account. If the protocol - * doesn't need to send anything, then the state of the account - * will be set to 'Unregistered', and related objects destroyed. - * - * @param accountId Account to unregister - * @return true if the unregister method is send correctly - */ - bool unregisterAccount(const AccountID& accountId); - - /** - * Send registration to all enabled accounts - * - * @return false if exosip or the network checking fails - */ - bool initRegisterAccounts(); - - /** - * True if we tried to register Once - */ - bool _hasTriedToRegister; - - - /** - * Undocumented - */ - bool sendTextMessage(const AccountID& accountId, const std::string& to, const std::string& message); - - /* - * Handle choice of the DTMF-send-way - * - * @param id: callid of the line. - * @param code: pressed key. - */ - bool sendDtmf(const CallID& id, char code); - bool playDtmf(char code, bool isTalking); - bool playTone (); - bool playToneWithMessage (); - void stopTone(bool stopAudio/*=true*/); - - // From links - /** - * When receiving a new incoming call, add it to the callaccount map - * and notify user - * @param call A call pointer - * @param accountid an account id - * @return true if the call was added correctly - */ - bool incomingCall(Call* call, const AccountID& accountId); - void peerAnsweredCall(const CallID& id); - void peerRingingCall(const CallID& id); - void peerHungupCall(const CallID& id); - void incomingMessage(const AccountID& accountId, const std::string& message); - - void displayTextMessage (const CallID& id, const std::string& message); - void displayErrorText (const CallID& id, const std::string& message); - void displayError(const std::string& error); - void displayStatus(const std::string& status); - void displayConfigError(const std::string& message); - - void startVoiceMessageNotification(const AccountID& accountId, const std::string& nb_msg); - void stopVoiceMessageNotification(const AccountID& accountId); - - /** Notify the user that registration succeeded */ - void registrationSucceed(const AccountID& accountId); - /** Notify the user that unregistration succeeded */ - void unregistrationSucceed(const AccountID& accountId); - /** Notify the user that registration failed */ - void registrationFailed(const AccountID& accountId); - /** Notify the user that registration is trying */ - void registrationTrying(const AccountID& accountId); - void sendRegister( const AccountID& accountId , bool expire ); - // configuration function requests - - /** - * Start events thread. This function actually only calls the private - * initRegisterVoIPLink(). - * - * This function should definitively be renamed! - * - * @todo Receive account name (???) - * - * DEPRECATED - */ - //bool getEvents(); - - // - bool getZeroconf(const std::string& sequenceId); - bool attachZeroconfEvents(const std::string& sequenceId, Pattern::Observer& observer); - bool detachZeroconfEvents(Pattern::Observer& observer); - bool getCallStatus(const std::string& sequenceId); - - /** - * Get account list - * @return A list of accoundIDs - */ - std::vector< std::string > getAccountList(); - - /** - * Retrieve details about a given account - */ - std::map< std::string, std::string > getAccountDetails(const AccountID& accountID); - - /** - * Save the details of an existing account, given the account ID - * - * This will load the configuration map with the given data. - * It will also register/unregister links where the 'Enabled' switched. - */ - void setAccountDetails( const ::DBus::String& accountID, - const std::map< ::DBus::String, ::DBus::String >& details ); - - /** - * Add a new account, and give it a new account ID automatically - */ - void addAccount(const std::map< ::DBus::String, ::DBus::String >& details); - - /** - * Delete an existing account, unregister VoIPLink associated, and - * purge from configuration. - */ - void removeAccount(const AccountID& accountID); - - /* - * Get the default account - * @return The default account - */ - std::string getDefaultAccount(); - - - /** - * Get the list of codecs we supports, not ordered - * @return The list of the codecs - */ - std::vector< ::DBus::String > getCodecList( void ); - /** - * Get the info about one codec - * Name / CLock rate / bitrate / bandwidth - * @param payload The payload of the codec - * @return The information - */ - std::vector< ::DBus::String > getCodecDetails( const ::DBus::Int32& payload); - - /** - * Get a list of supported input audio plugin - * @return List of names - */ - std::vector< std::string> getInputAudioPluginList(void); - - /** - * Get a list of supported output audio plugin - * @return List of names - */ - std::vector< std::string> getOutputAudioPluginList(void); - - /** - * Set input audio plugin - */ - void setInputAudioPlugin(const std::string& audioPlugin); - - /** - * Set output audio plugin - */ - void setOutputAudioPlugin(const std::string& audioPlugin); - - /** - * Get list of supported audio output device - */ - std::vector<std::string> getAudioOutputDeviceList(void); - - /** - * Set audio output device - */ - void setAudioOutputDevice(const int index); - - /** - * Get list of supported audio input device - */ - std::vector<std::string> getAudioInputDeviceList(void); - - /** - * Set audio input device - */ - void setAudioInputDevice(const int index); - - /** - * Get string array representing integer indexes of output and input device - */ - std::vector<std::string> getCurrentAudioDevicesIndex(); - - /** - * Get index of an audio device - */ - int getAudioDeviceIndex( const std::string name ); - - /* - * Get current alsa plugin - */ - std::string getCurrentAudioOutputPlugin( void ); - - /** - * Convert a list of payload in a special format, readable by the server. - * Required format: payloads separated with one slash. - * @return std::string The serializabled string - */ - std::string serialize(std::vector<std::string> v); - - int isIax2Enabled( void ); - int isRingtoneEnabled( void ); - void ringtoneEnabled( void ); - std::string getRingtoneChoice( void ); - void setRingtoneChoice( const std::string& ); - int getDialpad( void ); - void setDialpad( void ); - int isStartHidden( void ); - void startHidden( void ); - int popupMode( void ); - void switchPopupMode( void ); - - - /** - * Inverse of serialize - */ - std::vector<std::string> retrieveActiveCodecs( void ); - - /** - * Get and set the list of the active codecs - */ - std::vector< ::DBus::String > getActiveCodecList( void ); - void setActiveCodecList( const std::vector< ::DBus::String >& list); - - /* - * Set an account as default - * @param The ID of the account we want to set as default - */ - void setDefaultAccount(const AccountID& accountID); - - /* - * Notify the client that an error occured - * @param errMsg The error message that should popup on the client side - */ - void notifyErrClient( const ::DBus::Int32& errCode ); - - bool getConfigAll(const std::string& sequenceId); - bool getConfig(const std::string& section, const std::string& name, TokenList& arg); - bool setConfig(const std::string& section, const std::string& name, const std::string& value); - bool setConfig(const std::string& section, const std::string& name, int value); - bool getConfigList(const std::string& sequenceId, const std::string& name); - void selectAudioDriver(void); - - /** - * Set Audio Driver with switchName == audiodriver - * @param sflphoned internal parameter to change - * @param message to return to the user - * @return true if everything is ok - */ - bool setSwitch(const std::string& switchName, std::string& message); - - // configuration function for extern - // throw an Conf::ConfigTreeItemException if not found - /** Get a int from the config tree */ - int getConfigInt(const std::string& section, const std::string& name); - /** Get a string from the config tree */ - std::string getConfigString(const std::string& section, const std::string& name); - - /** - * Handle audio sounds heard by a caller while they wait for their - * connection to a called party to be completed. - */ - void ringback (); - - /** - * Handle played music when an incoming call occurs - */ - void ringtone (); - void congestion (); - void callBusy(const CallID& id); - void callFailure(const CallID& id); - - /** @return 0 if no tone (init before calling this function) */ - AudioLoop* getTelephoneTone(); - /** @return 0 if the wav is stopped */ - AudioLoop* getTelephoneFile(); - - /** - * @return true is there is one or many incoming call waiting - * new call, not anwsered or refused - */ - bool incomingCallWaiting(void); - /** - * Notification of incoming call when you are already busy - */ - void notificationIncomingCall(void); - - - /* - * Inline functions to manage volume control - * Read by main thread and AudioLayer thread - * Write by main thread only - */ - unsigned short getSpkrVolume(void) { return _spkr_volume; } - void setSpkrVolume(unsigned short spkr_vol) { _spkr_volume = spkr_vol; } - unsigned short getMicVolume(void) { return _mic_volume; } - void setMicVolume(unsigned short mic_vol) { _mic_volume = mic_vol; } - - // Manage information about firewall - /* - * Get information about firewall - * @param stunSvrAddr: stun server - * @param port port number to open to test the connection - * @return true if the connection is successful - */ - bool getStunInfo(StunAddress4& stunSvrAddr, int port); - - inline int getFirewallPort(void) { return _firewallPort; } - inline void setFirewallPort(int port) { _firewallPort = port; } - inline std::string getFirewallAddress (void) { return _firewallAddr; } - - /** - * If you are behind a NAT, you have to use STUN server, specified in - * STUN configuration(you can change this one by default) to give you an - * public IP address and assign a port number. - * Note: Set firewall port/address retreive - * @param svr : serveur on which to send request - * @param port : on which port we want to listen to - * - * Return true if we are behind a NAT (without error) - */ - bool behindNat(const std::string& svr, int port); - - /** - * Init default values for the different fields in the config file. - * Fills the local _config (Conf::ConfigTree) with the default contents. - * - * Called in main.cpp, just before Manager::init(). - */ - void initConfigFile (void); - - /** - * Tell if the setup was already loaded - */ - bool hasLoadedSetup() { return _setupLoaded; } - - /** Return a new random callid that is not present in the list - * @return a brand new callid - */ - CallID getNewCallID(); - - /** - * Get the current call id - * @return the call id or "" - */ - const CallID& getCurrentCallId(); - - /** - * Check if a call is the current one - * @param id the new callid - * @return if the id is the current call - */ - bool isCurrentCall(const CallID& callId); - - /** - * Map accounts parameters ( authname - hostname ) to an account ID - */ - AccountID getAccountFromEvent( std::string authname ); -private: - /** - * Create .PROGNAME directory in home user and create - * configuration tree from the settings file if this file exists. - * - * @return 0 if creating file failed - * 1 if config-file exists - * 2 if file doesn't exist yet. - */ - int createSettingsPath (void); - - /* - * Initialize audiocodec with config setting - */ - void initAudioCodec(void); - - /* - * Initialize audiodriver - */ - void initAudioDriver(void); - - /* - * Initialize zeroconf module and scanning - */ - void initZeroconf(void); - - /* - * Init the Gui interface (after setting it) inside setGui - */ - void initGui(); - - /* - * Init the volume for speakers/micro from 0 to 100 value - */ - void initVolume(); - - /** - * Configuration - */ - bool getDirListing(const std::string& sequenceId, const std::string& path, int *nbFile); - bool getAudioDeviceList(const std::string& sequenceId, int ioDeviceMask); - Conf::ConfigTree _config; - bool getCountryTones(const std::string& sequenceId); - void sendCountryTone(const std::string& sequenceId, int index, const std::string& name); - - - - /** - * Tell if there is a current call processed - * @return true if there is a current call - */ - bool hasCurrentCall(); - - /** - * Switch of current call id - * @param id the new callid - */ - void switchCall(const CallID& id); - - /** Current Call ID */ - CallID _currentCallId2; - - /** Protected current call access */ - ost::Mutex _currentCallMutex; - - - /* - * Play one tone - * @return false if the driver is uninitialize - */ - bool playATone(Tone::TONEID toneId); - - // - // Multithread variable with extern accessor and change only inside the main thread - // - /** Vector of CodecDescriptor */ - CodecDescriptor* _codecBuilder; - - // - // Sound variable - // - AudioLayer* _audiodriver; - - // Main thread - DTMF* _dtmfKey; - - // map of codec (for configlist request) - CodecDescriptor _codecDescriptorMap; - - ///////////////////// - // Protected by Mutex - ///////////////////// - ost::Mutex _toneMutex; - TelephoneTone* _telephoneTone; - AudioFile _audiofile; - - // To handle volume control - short _spkr_volume; - short _mic_volume; - short _mic_volume_before_mute; - // End of sound variable - - - // Multithread variable (protected by _mutex) - // - /** Mutex to protect access to code section */ - ost::Mutex _mutex; - - // - // Multithread variable (non protected) - // - DBusManagerImpl * _dbus; - - /** Waiting Call Vectors */ - CallIDSet _waitingCall; - /** Protect waiting call list, access by many voip/audio threads */ - ost::Mutex _waitingCallMutex; - /** Number of waiting call, synchronize with waitingcall callidvector */ - unsigned int _nbIncomingWaitingCall; - /** - * Add incoming callid to the waiting list - * @param id CallID to add - */ - void addWaitingCall(const CallID& id); - /** - * Remove incoming callid to the waiting list - * @param id CallID to remove - */ - void removeWaitingCall(const CallID& id); - /** - * Tell if a call is waiting and should be remove - * @param id CallID to test - * @return true if the call is waiting - */ - bool isWaitingCall(const CallID& id); - - /** - * Path of the ConfigFile - */ - std::string _path; - int _exist; - int _setupLoaded; - - // To handle firewall - int _firewallPort; - std::string _firewallAddr; - - // tell if we have zeroconf is enabled - int _hasZeroconf; + public: + ManagerImpl (void); + ~ManagerImpl (void); + + /** + * Initialisation of thread (sound) and map. + * Init a new VoIPLink, audio codec and audio driver + */ + void init (void); + + /** + * Terminate all thread (sound, link) and unload AccountMap + */ + void terminate (void); + + /** + * Set user interface manager. + * @param man The DBUS interface implementation + */ + void setDBusManager (DBusManagerImpl* man) { _dbus = man; } + + /** + * Accessor to audiodriver. + * it's multi-thread and use mutex internally + * @return AudioLayer* The audio layer object + */ + AudioLayer* getAudioDriver(void) const { return _audiodriver; } + + /** + * Get a descriptor map of codec available + * @return CodecDescriptor The internal codec map + */ + CodecDescriptor& getCodecDescriptorMap(void) {return _codecDescriptorMap;} + + /** + * Functions which occur with a user's action + * Place a new call + * @param accountId The account to make tha call with + * @param id The call identifier + * @param to The recipient of the call + * @return bool true on success + * false otherwise + */ + bool outgoingCall(const AccountID& accountId, const CallID& id, const std::string& to); + + /** + * Functions which occur with a user's action + * Answer the call + * @param id The call identifier + */ + bool answerCall(const CallID& id); + + /** + * Functions which occur with a user's action + * Hangup the call + * @param id The call identifier + */ + bool hangupCall(const CallID& id); + + /** + * Functions which occur with a user's action + * Cancel the call + * @param id The call identifier + */ + bool cancelCall(const CallID& id); + + /** + * Functions which occur with a user's action + * Put the call on hold + * @param id The call identifier + */ + bool onHoldCall(const CallID& id); + + /** + * Functions which occur with a user's action + * Put the call off hold + * @param id The call identifier + */ + bool offHoldCall(const CallID& id); + + /** + * Functions which occur with a user's action + * Transfer the call + * @param id The call identifier + * @param to The recipient of the transfer + */ + bool transferCall(const CallID& id, const std::string& to); + + /** + * Functions which occur with a user's action + * Refuse the call + * @param id The call identifier + */ + bool refuseCall(const CallID& id); + + /** + * Save config to file + * @return true on success + * false otherwise + */ + bool saveConfig (void); + + /** + * Send registration to all enabled accounts + * @return false if exosip or the network checking fails + */ + bool initRegisterAccounts(); + + /** + * @return true if we tried to register once + */ + bool _hasTriedToRegister; + + /** + * Undocumented + */ + bool sendTextMessage(const AccountID& accountId, const std::string& to, const std::string& message); + + /** + * Handle choice of the DTMF-send-way + * @param id: callid of the line. + * @param code: pressed key. + */ + bool sendDtmf(const CallID& id, char code); + + /** + * Play the dtmf-associated sound + * @param code The pressed key + * @param isTalking In conversation or not. Useful to know whether or not the sound streams are started + */ + bool playDtmf(char code, bool isTalking); + + /** + * Play a ringtone + * @return bool True on success + * false otherwise + */ + bool playTone (); + + /** + * Play a special ringtone ( BUSY ) if there's at least one message on the voice mail + * @return bool True on success + * false otherwise + */ + bool playToneWithMessage (); + + /** + * Acts on the audio streams and audio files + * @param stopAudio Tells whether or not to stop the streams + */ + void stopTone(bool stopAudio); + + /** + * When receiving a new incoming call, add it to the callaccount map + * and notify user + * @param call A call pointer + * @param accountId an account id + * @return bool True if the call was added correctly + */ + bool incomingCall(Call* call, const AccountID& accountId); + + /** + * Notify the user that the recipient of the call has answered and the put the + * call in Current state + * @param id The call identifier + */ + void peerAnsweredCall(const CallID& id); + + /** + * Rings back because the outgoing call is ringing and the put the + * call in Ringing state + * @param id The call identifier + */ + void peerRingingCall(const CallID& id); + + /** + * Put the call in Hungup state, remove the call from the list + * @param id The call identifier + */ + void peerHungupCall(const CallID& id); + + /** + * Notify the client with an incoming message + * @param accountId The account identifier + * @param message The content of the message + */ + void incomingMessage(const AccountID& accountId, const std::string& message); + + /** + * Notify the user he has voice mails + * @param accountId The account identifier + * @param nb_msg The number of messages + */ + void startVoiceMessageNotification(const AccountID& accountId, const std::string& nb_msg); + + /** + * Notify the user that registration succeeded + * @param accountId The account identifier + */ + void registrationSucceed(const AccountID& accountId); + + /** + * Notify the user that unregistration succeeded + * @param accountId The account identifier + */ + void unregistrationSucceed(const AccountID& accountId); + + /** + * Notify the user that registration failed + * @param accountId The account identifier + */ + void registrationFailed(const AccountID& accountId); + + /** + * Notify the user that registration is trying + * @param accountId The account identifier + */ + void registrationTrying(const AccountID& accountId); + + /** + * ConfigurationManager - Send registration request + * @param accountId The account to register/unregister + * @param expire The flag for the type of registration + * 0 for unregistration request + * 1 for registration request + */ + void sendRegister( const ::DBus::String& accountId , bool expire ); + + bool getZeroconf(const std::string& sequenceId); + bool attachZeroconfEvents(const std::string& sequenceId, Pattern::Observer& observer); + bool detachZeroconfEvents(Pattern::Observer& observer); + bool getCallStatus(const std::string& sequenceId); + + /** + * Get account list + * @return std::vector<std::string> A list of accoundIDs + */ + std::vector< std::string > getAccountList(); + + /** + * Retrieve details about a given account + * @param accountID The account identifier + * @return std::map< std::string, std::string > The account details + */ + std::map< std::string, std::string > getAccountDetails(const AccountID& accountID); + + /** + * Save the details of an existing account, given the account ID + * This will load the configuration map with the given data. + * It will also register/unregister links where the 'Enabled' switched. + * @param accountID The account identifier + * @param details The account parameters + */ + void setAccountDetails( const ::DBus::String& accountID, + const std::map< ::DBus::String, ::DBus::String >& details ); + + /** + * Add a new account, and give it a new account ID automatically + * @param details The new account parameters + */ + void addAccount(const std::map< ::DBus::String, ::DBus::String >& details); + + /** + * Delete an existing account, unregister VoIPLink associated, and + * purge from configuration. + * @param accountID The account unique ID + */ + void removeAccount(const AccountID& accountID); + + /** + * Get the list of codecs we supports, not ordered + * @return The list of the codecs + */ + std::vector< ::DBus::String > getCodecList( void ); + + /** + * Get the info about one codec + * Name / Clock rate / bitrate / bandwidth + * @param payload The payload of the codec + * @return std::vector<::DBus::string> The information + */ + std::vector< ::DBus::String > getCodecDetails( const ::DBus::Int32& payload); + + /** + * Get a list of supported input audio plugin + * @return std::vector<std::string> List of names + */ + std::vector< std::string> getInputAudioPluginList(void); + + /** + * Get a list of supported output audio plugin + * @return std::vector<std::string> List of names + */ + std::vector< std::string> getOutputAudioPluginList(void); + + /** + * Set input audio plugin + * @param audioPlugin The audio plugin + */ + void setInputAudioPlugin(const std::string& audioPlugin); + + /** + * Set output audio plugin + * @param audioPlugin The audio plugin + */ + void setOutputAudioPlugin(const std::string& audioPlugin); + + /** + * Get list of supported audio output device + * @return std::vector<std::string> A list of the audio devices supporting playback + */ + std::vector<std::string> getAudioOutputDeviceList(void); + + /** + * Set audio output device + * @param index The index of the soundcard + */ + void setAudioOutputDevice(const int index); + + /** + * Get list of supported audio input device + * @return std::vector<std::string> A list of the audio devices supporting capture + */ + std::vector<std::string> getAudioInputDeviceList(void); + + /** + * Set audio input device + * @param index The index of the soundcard + */ + void setAudioInputDevice(const int index); + + /** + * Get string array representing integer indexes of output and input device + * @return std::vector<std::string> A list of the current audio devices + */ + std::vector<std::string> getCurrentAudioDevicesIndex(); + + /** + * Get index of an audio device + * @param name The string description of an audio device + * @return int His index + */ + int getAudioDeviceIndex( const std::string name ); + + /* + * Get current alsa plugin + * @return std::string The Alsa plugin + */ + std::string getCurrentAudioOutputPlugin( void ); + + /** + * Convert a list of payload in a special format, readable by the server. + * Required format: payloads separated with one slash. + * @return std::string The serializabled string + */ + std::string serialize(std::vector<std::string> v); + + /** + * Tells if IAX2 support is enabled + * @return int 1 if IAX2 is enabled + * 0 otherwise + */ + int isIax2Enabled( void ); + + /** + * Ringtone option. + * If ringtone is enabled, ringtone on incoming call use custom choice. If not, only standart tone. + * @return int 1 if enabled + * 0 otherwise + */ + int isRingtoneEnabled( void ); + + /** + * Set the ringtone option + * Inverse current value + */ + void ringtoneEnabled( void ); + + /** + * Get the ringtone + * @return gchar* The file name selected as a ringtone + */ + std::string getRingtoneChoice( void ); + + /** + * Set a ringtone + * @param tone The file name of the ringtone + */ + void setRingtoneChoice( const std::string& ); + + /** + * Tells if the user wants to display the dialpad or not + * @return int 1 if dialpad has to be displayed + * 0 otherwise + */ + int getDialpad( void ); + + /** + * Set the dialpad visible or not + */ + void setDialpad( void ); + + /** + * Configure the start-up option + * @return int 1 if SFLphone should start in the system tray + * 0 otherwise + */ + int isStartHidden( void ); + + /** + * Configure the start-up option + * At startup, SFLphone can be displayed or start hidden in the system tray + */ + void startHidden( void ); + + /** + * Configure the popup behaviour + * @return int 1 if it should popup on incoming calls + * 0 if it should never popups + */ + int popupMode( void ); + + /** + * Configure the popup behaviour + * When SFLphone is in the system tray, you can configure when it popups + * Never or only on incoming calls + */ + void switchPopupMode( void ); + + /** + * Retrieve the formatted list of codecs payload in the user config file and + * load in the active list of codecs + * @return std::vector<std::string> The vector containing the active codecs + */ + std::vector<std::string> retrieveActiveCodecs( void ); + + /** + * Get the list of the active codecs + * @return std::vector< ::DBus::String > The list of active codecs + */ + std::vector< ::DBus::String > getActiveCodecList( void ); + + /** + * Set the list of the active codecs + * @param list The new list of active codecs + */ + void setActiveCodecList( const std::vector< ::DBus::String >& list); + + /* + * Notify the client that an error occured + * @param errCode The error code. Could be: ALSA_CAPTURE_ERROR + * ALSA_PLAYBACK_ERROR + */ + void notifyErrClient( const ::DBus::Int32& errCode ); + + /** + * Retrieve in the configuration tree the value of a parameter in a specific section + * @param section The section to look in + * @param name The name of the parameter you want to get + * @param arg Undocumented + * @return bool true on success + * false otherwise + */ + bool getConfig(const std::string& section, const std::string& name, TokenList& arg); + + /** + * Change a specific value in the configuration tree. + * This value will then be saved in the user config file sflphonedrc + * @param section The section name + * @param name The parameter name + * @param value The new string value + * @return bool true on success + * false otherwise + */ + bool setConfig(const std::string& section, const std::string& name, const std::string& value); + + /** + * Change a specific value in the configuration tree. + * This value will then be saved in the user config file sflphonedrc + * @param section The section name + * @param name The parameter name + * @param value The new int value + * @return bool true on success + * false otherwise + */ + bool setConfig(const std::string& section, const std::string& name, int value); + + /** + * Get a int from the configuration tree + * Throw an Conf::ConfigTreeItemException if not found + * @param section The section name to look in + * @param name The parameter name + * @return int The int value + */ + int getConfigInt(const std::string& section, const std::string& name); + + /** + * Get a string from the configuration tree + * Throw an Conf::ConfigTreeItemException if not found + * @param section The section name to look in + * @param name The parameter name + * @return sdt::string The string value + */ + std::string getConfigString(const std::string& section, const std::string& name); + + /** + * Retrieve the soundcards index in the user config file and try to open audio devices + * with a specific alsa plugin. + * Set the audio layer sample rate + */ + void selectAudioDriver(void); + + /** + * Handle audio sounds heard by a caller while they wait for their + * connection to a called party to be completed. + */ + void ringback (); + + /** + * Handle played music when an incoming call occurs + */ + void ringtone (); + + /** + * Handle played music when a congestion occurs + */ + void congestion (); + + /** + * Handle played sound when a call can not be conpleted because of a busy recipient + */ + void callBusy(const CallID& id); + + /** + * Handle played sound when a failure occurs + */ + void callFailure(const CallID& id); + + /** + * Retrieve the current telephone tone + * @return AudioLoop* The audio tone or 0 if no tone (init before calling this function) + */ + AudioLoop* getTelephoneTone(); + + /** + * Retrieve the current telephone file + * @return AudioLoop* The audio file or 0 if the wav is stopped + */ + AudioLoop* getTelephoneFile(); + + /** + * @return true is there is one or many incoming call waiting + * new call, not anwsered or refused + */ + bool incomingCallWaiting(void); + + /** + * Notification of incoming call when you are already busy + */ + void notificationIncomingCall(void); + + /* + * Inline functions to manage speaker volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @return unsigned short The volume value + */ + unsigned short getSpkrVolume(void) { return _spkr_volume; } + + /* + * Inline functions to manage speaker volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @param spkr_vol The volume value + */ + void setSpkrVolume(unsigned short spkr_vol) { _spkr_volume = spkr_vol; } + + /* + * Inline functions to manage mic volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @return unsigned short The volume value + */ + unsigned short getMicVolume(void) { return _mic_volume; } + + /* + * Inline functions to manage mic volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @param mic_vol The volume value + */ + void setMicVolume(unsigned short mic_vol) { _mic_volume = mic_vol; } + + // Manage information about firewall + + /* + * Get information about firewall + * @param stunSvrAddr: stun server + * @param port port number to open to test the connection + * @return true if the connection is successful + */ + bool getStunInfo(StunAddress4& stunSvrAddr, int port); + + /* + * Inline functions to manage firewall settings + * @return int The firewall port + */ + inline int getFirewallPort(void) { return _firewallPort; } + + /* + * Inline functions to manage firewall settings + * @param port The firewall port + */ + inline void setFirewallPort(int port) { _firewallPort = port; } + + /* + * Inline functions to manage firewall settings + * @return std::string The firewall address + */ + inline std::string getFirewallAddress (void) { return _firewallAddr; } + + /** + * If you are behind a NAT, you have to use STUN server, specified in + * STUN configuration(you can change this one by default) to give you an + * public IP address and assign a port number. + * Note: Set firewall port/address retreive + * @param svr Server on which to send request + * @param port On which port we want to listen to + * @return true if we are behind a NAT (without error) + */ + bool behindNat(const std::string& svr, int port); + + /** + * Init default values for the different fields in the config file. + * Fills the local _config (Conf::ConfigTree) with the default contents. + * Called in main.cpp, just before Manager::init(). + */ + void initConfigFile (void); + + /** + * Tell if the setup was already loaded + * @return bool True if yes + * false otherwise + */ + bool hasLoadedSetup() { return _setupLoaded; } + + /** + * Return a new random callid that is not present in the list + * @return CallID A brand new callid + */ + CallID getNewCallID(); + + /** + * Get the current call id + * @return CallID The call id or "" + */ + const CallID& getCurrentCallId(); + + /** + * Check if a call is the current one + * @param callId the new callid + * @return bool True if the id is the current call + */ + bool isCurrentCall(const CallID& callId); + + private: + /** + * Create .PROGNAME directory in home user and create + * configuration tree from the settings file if this file exists. + * + * @return 0 if creating file failed + * 1 if config-file exists + * 2 if file doesn't exist yet. + */ + int createSettingsPath (void); + + /* + * Initialize audiocodec with config setting + */ + void initAudioCodec(void); + + /* + * Initialize audiodriver + */ + void initAudioDriver(void); + + /* + * Initialize zeroconf module and scanning + */ + void initZeroconf(void); + + /* + * Init the volume for speakers/micro from 0 to 100 value + */ + void initVolume(); + + /** + * Tell if there is a current call processed + * @return bool True if there is a current call + */ + bool hasCurrentCall(); + + /** + * Switch of current call id + * @param id The new callid + */ + void switchCall(const CallID& id); + + /* + * Play one tone + * @return false if the driver is uninitialize + */ + bool playATone(Tone::TONEID toneId); + + /** The configuration tree. It contains accounts parameters, general user settings ,audio settings, ... */ + Conf::ConfigTree _config; + + /** Current Call ID */ + CallID _currentCallId2; + + /** Protected current call access */ + ost::Mutex _currentCallMutex; + + /** Vector of CodecDescriptor */ + CodecDescriptor* _codecBuilder; + + /** Audio layer */ + AudioLayer* _audiodriver; + + // Main thread + + DTMF* _dtmfKey; + + // map of codec (for configlist request) + CodecDescriptor _codecDescriptorMap; + + ///////////////////// + // Protected by Mutex + ///////////////////// + ost::Mutex _toneMutex; + TelephoneTone* _telephoneTone; + AudioFile _audiofile; + + // To handle volume control + short _spkr_volume; + short _mic_volume; + // End of sound variable + + + // Multithread variable (protected by _mutex) + // + /** Mutex to protect access to code section */ + ost::Mutex _mutex; + + // Multithread variable (non protected) + DBusManagerImpl * _dbus; + + /** Waiting Call Vectors */ + CallIDSet _waitingCall; + + /** Protect waiting call list, access by many voip/audio threads */ + ost::Mutex _waitingCallMutex; + + /** Number of waiting call, synchronize with waitingcall callidvector */ + unsigned int _nbIncomingWaitingCall; + + /** + * Add incoming callid to the waiting list + * @param id CallID to add + */ + void addWaitingCall(const CallID& id); + + /** + * Remove incoming callid to the waiting list + * @param id CallID to remove + */ + void removeWaitingCall(const CallID& id); + + /** + * Tell if a call is waiting and should be remove + * @param id CallID to test + * @return bool True if the call is waiting + */ + bool isWaitingCall(const CallID& id); + + /** + * Path of the ConfigFile + */ + std::string _path; + int _exist; + int _setupLoaded; + + // To handle firewall + int _firewallPort; + std::string _firewallAddr; + + // tell if we have zeroconf is enabled + int _hasZeroconf; #ifdef USE_ZEROCONF - // DNSService contain every zeroconf services - // configuration detected on the network - DNSService *_DNSService; + // DNSService contain every zeroconf services + // configuration detected on the network + DNSService *_DNSService; #endif - /** Map to associate a CallID to the good account */ - CallAccountMap _callAccountMap; - /** Mutex to lock the call account map (main thread + voiplink thread) */ - ost::Mutex _callAccountMapMutex; - - /** Associate a new CallID to a AccountID - * Protected by mutex - * @param callID the new CallID not in the list yet - * @param accountID the known accountID present in accountMap - * @return true if the new association is create - */ - bool associateCallToAccount(const CallID& callID, const AccountID& accountID); - - /** Return the AccountID from a CallID - * Protected by mutex - * @param callID the CallID in the list - * @return the accountID associated or "" if the callID is not found - */ - AccountID getAccountFromCall(const CallID& callID); - - /** Remove a CallID/AccountID association - * Protected by mutex - * @param callID the CallID to remove - * @return true if association is removed - */ - bool removeCallAccount(const CallID& callID); - - /** Contains a list of account (sip, aix, etc) and their respective voiplink/calls */ - AccountMap _accountMap; - - /** - * Load the account from configuration - * @return number of account - */ - short loadAccountMap(); - - /** - * Unload the account (delete them) - */ - void unloadAccountMap(); - - /** - * Tell if an account exists - * @param accountID account ID check - */ - bool accountExists(const AccountID& accountID); - - /** - * Get an account pointer - * @param accountID account ID to get - * @param the account pointer or 0 - */ - Account* getAccount(const AccountID& accountID); - - /** - * Get the voip link from the account pointer - * @param accountID account ID to get - * @param the voip link from the account pointer or 0 - */ - VoIPLink* getAccountLink(const AccountID& accountID); - - - - #ifdef TEST - bool testCallAccountMap(); - bool testAccountMap(); - #endif + /** Map to associate a CallID to the good account */ + CallAccountMap _callAccountMap; + + /** Mutex to lock the call account map (main thread + voiplink thread) */ + ost::Mutex _callAccountMapMutex; + + /** Associate a new CallID to a AccountID + * Protected by mutex + * @param callID the new CallID not in the list yet + * @param accountID the known accountID present in accountMap + * @return bool True if the new association is create + */ + bool associateCallToAccount(const CallID& callID, const AccountID& accountID); + + /** Return the AccountID from a CallID + * Protected by mutex + * @param callID the CallID in the list + * @return AccountID The accountID associated or "" if the callID is not found + */ + AccountID getAccountFromCall(const CallID& callID); + + /** Remove a CallID/AccountID association + * Protected by mutex + * @param callID the CallID to remove + * @return bool True if association is removed + */ + bool removeCallAccount(const CallID& callID); + + /** Contains a list of account (sip, aix, etc) and their respective voiplink/calls */ + AccountMap _accountMap; + + /** + * Load the account from configuration + * @return short Number of account + */ + short loadAccountMap(); + + /** + * Unload the account (delete them) + */ + void unloadAccountMap(); + + /** + * Tell if an account exists + * @param accountID account ID check + * @return bool True if the account exists + * false otherwise + */ + bool accountExists(const AccountID& accountID); + + /** + * Get an account pointer + * @param accountID account ID to get + * @return Account* The account pointer or 0 + */ + Account* getAccount(const AccountID& accountID); + + /** + * Get the voip link from the account pointer + * @param accountID Account ID to get + * @return VoIPLink* The voip link from the account pointer or 0 + */ + VoIPLink* getAccountLink(const AccountID& accountID); + +#ifdef TEST + bool testCallAccountMap(); + bool testAccountMap(); +#endif }; diff --git a/src/sipaccount.h b/src/sipaccount.h index 23c2fc3f529f09821820f238c9faa3e626d261dd..e542032b02cd4ede155d3548d120aaf4e9c5cb6d 100644 --- a/src/sipaccount.h +++ b/src/sipaccount.h @@ -24,19 +24,37 @@ /** - * A SIP Account specify SIP specific functions and object (SIPCall/SIPVoIPLink) - * @author Yan Morin <yan.morin@gmail.com> + * @file sipaccount.h + * @brief A SIP Account specify SIP specific functions and object (SIPCall/SIPVoIPLink) */ + class SIPAccount : public Account { public: + /** + * Constructor + * @param accountID The account identifier + */ SIPAccount(const AccountID& accountID); + /** + * Virtual destructor + */ virtual ~SIPAccount(); - /** Actually unuseful, since config loading is done in init() */ + /** + * Actually unuseful, since config loading is done in init() + */ void loadConfig(); + + /** + * Initialize the SIP voip link with the account parameters and send registration + */ void registerVoIPLink(); + + /** + * Send unregistration and clean all related stuff ( calls , thread ) + */ void unregisterVoIPLink(); private: diff --git a/src/sipcall.h b/src/sipcall.h index 3883380e3f69cc60e93d0cb0f80a263333893bcc..a74885500707958e326a034690f66c20d119a52c 100644 --- a/src/sipcall.h +++ b/src/sipcall.h @@ -28,112 +28,147 @@ class AudioCodec; /** - * SIPCall are SIP implementation of a normal Call - * @author Yan Morin <yan.morin@gmail.com> + * @file sipcall.h + * @brief SIPCall are SIP implementation of a normal Call */ class SIPCall : public Call { -public: + public: + + /** + * Constructor + * @param id The call identifier + * @param type The type of the call. Could be Incoming + * Outgoing + */ SIPCall(const CallID& id, Call::CallType type); + /** + * Destructor + */ ~SIPCall(); - /** @return SIP call id : protected by eXosip lock */ - int getCid() { return _cid; } - /** @param cid SIP call id : protected by eXosip lock */ - void setCid(int cid) { _cid = cid ; } - /** @return SIP domain id : protected by eXosip lock */ - int getDid() { return _did; } - /** @param did SIP domain id : protected by eXosip lock */ - void setDid(int did) { _did = did; } - /** @return SIP transaction id : protected by eXosip lock */ - int getTid() { return _tid; } - /** @param did SIP transaction id : protected by eXosip lock */ - void setTid(int tid) { _tid = tid; } - - /** - * Setup incoming call, and verify for errors, before ringing the user. - * @param event eXosip Event - */ - bool SIPCallInvite(eXosip_event_t *event); - - /** - * newReinviteCall is called when the IP-Phone user receives a change in the call - * it's almost an newIncomingCall but we send a 200 OK - * See: 3.7. Session with re-INVITE (IP Address Change) - * @param event eXosip Event - * @return true if ok - */ - bool SIPCallReinvite(eXosip_event_t *event); - - /** - * Peer answered to a call (on hold or not) - * @param event eXosip Event - * @return true if ok - */ - bool SIPCallAnswered(eXosip_event_t *event); - - /** - * We retreive final SDP info if they changed - * @param event eXosip Event - * @return true if ok (change / no change) or false on error - */ - bool SIPCallAnsweredWithoutHold(eXosip_event_t *event); - - //TODO: humm? - int sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg); - - -private: - - // TODO: hum??? - int sdp_analyse_attribute (sdp_message_t * sdp, sdp_media_t * med); - /** - * Set peer name and number with event->request->from - * @param event eXosip event - * @return false the event is invalid - */ - - bool setPeerInfoFromRequest(eXosip_event_t *event); - /** - * Get a valid remote SDP or return a 400 bad request response if invalid - * - * @param event eXosip event - * @return valid remote_sdp or 0 - */ - sdp_message_t* getRemoteSDPFromRequest(eXosip_event_t *event); - - /** - * Get a valid remote media or return a 415 unsupported media type - * - * @param tid transaction id - * @param remote_sdp Remote SDP pointer - * @return valid sdp_media_t or 0 - */ - sdp_media_t* getRemoteMedia(int tid, sdp_message_t* remote_sdp); - - /** - * Set Audio Port and Audio IP from Remote SDP Info - * @param remote_med Remote Media info - * @param remote_sdp Remote SDP pointer - * @return true if everything is set correctly - */ - bool setRemoteAudioFromSDP(sdp_media_t* remote_med, sdp_message_t* remote_sdp); - - /** - * Set Audio Codec with the remote choice - * @param remote_med Remote Media info - * @return true if everything is set correctly - */ - bool setAudioCodecFromSDP(sdp_media_t* remote_med, int tid); - - - /** SIP call id */ - int _cid; - /** SIP domain id */ - int _did; - /** SIP transaction id */ - int _tid; + /** + * Call Identifier + * @return int SIP call id : protected by eXosip lock + */ + int getCid() { return _cid; } + + /** + * Call Identifier + * @param cid SIP call id : protected by eXosip lock + */ + void setCid(int cid) { _cid = cid ; } + + /** + * Domain identifier + * @return int SIP domain id : protected by eXosip lock + */ + int getDid() { return _did; } + + /** + * Domain identifier + * @param did SIP domain id : protected by eXosip lock + */ + void setDid(int did) { _did = did; } + + /** + * Transaction identifier + * @return int SIP transaction id : protected by eXosip lock + */ + int getTid() { return _tid; } + + /** + * Transaction identifier + * @param tid SIP transaction id : protected by eXosip lock + */ + void setTid(int tid) { _tid = tid; } + + /** + * Setup incoming call, and verify for errors, before ringing the user. + * @param event eXosip Event + * @return bool True on success + * false otherwise + */ + bool SIPCallInvite(eXosip_event_t *event); + + /** + * newReinviteCall is called when the IP-Phone user receives a change in the call + * it's almost an newIncomingCall but we send a 200 OK + * See: 3.7. Session with re-INVITE (IP Address Change) + * @param event eXosip Event + * @return bool True if ok + */ + bool SIPCallReinvite(eXosip_event_t *event); + + /** + * Peer answered to a call (on hold or not) + * @param event eXosip Event + * @return bool True if ok + */ + bool SIPCallAnswered(eXosip_event_t *event); + + /** + * We retreive final SDP info if they changed + * @param event eXosip Event + * @return bool True if ok (change / no change) or false on error + */ + bool SIPCallAnsweredWithoutHold(eXosip_event_t *event); + + //TODO: humm? + int sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg); + + + private: + + // TODO: hum??? + int sdp_analyse_attribute (sdp_message_t * sdp, sdp_media_t * med); + + /** + * Set peer name and number with event->request->from + * @param event eXosip event + * @return bool False if the event is invalid + */ + bool setPeerInfoFromRequest(eXosip_event_t *event); + + /** + * Get a valid remote SDP or return a 400 bad request response if invalid + * @param event eXosip event + * @return sdp_message_t* A valid remote_sdp or 0 + */ + sdp_message_t* getRemoteSDPFromRequest(eXosip_event_t *event); + + /** + * Get a valid remote media or return a 415 unsupported media type + * @param tid transaction id + * @param remote_sdp Remote SDP pointer + * @return sdp_media_t* A valid sdp_media_t or 0 + */ + sdp_media_t* getRemoteMedia(int tid, sdp_message_t* remote_sdp); + + /** + * Set Audio Port and Audio IP from Remote SDP Info + * @param remote_med Remote Media info + * @param remote_sdp Remote SDP pointer + * @return bool True if everything is set correctly + */ + bool setRemoteAudioFromSDP(sdp_media_t* remote_med, sdp_message_t* remote_sdp); + + /** + * Set Audio Codec with the remote choice + * @param remote_med Remote Media info + * @return bool True if everything is set correctly + */ + bool setAudioCodecFromSDP(sdp_media_t* remote_med, int tid); + + /** SIP call id */ + int _cid; + + /** SIP domain id */ + int _did; + + /** SIP transaction id */ + int _tid; }; diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 741fd963e7a621ea6e15b1e6066ac2bc179f1db4..47320dce08b5c1f05ace808242036f79b4c9d7d5 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -215,12 +215,6 @@ SIPVoIPLink::loadSIPLocalIP() return returnValue; } -void -SIPVoIPLink::parseRequestUri( osip_uri_t* req ) -{ - // _debug("%d\n",req->url_header); -} - void SIPVoIPLink::getEvent() { @@ -313,7 +307,6 @@ SIPVoIPLink::getEvent() break; case EXOSIP_CALL_TIMEOUT: /** 17 < announce that call has failed */ _debugMid(" !EXOSIP_CALL_TIMEOUT\n"); - Manager::instance().displayError(" !EXOSIP Call Error not implemented yet"); break; /* Request related events within calls (except INVITE) */ @@ -339,7 +332,6 @@ SIPVoIPLink::getEvent() break; case EXOSIP_CALL_MESSAGE_GLOBALFAILURE: /** 24 < announce a failure. */ _debugMid(" !EXOSIP_CALL_MESSAGE_GLOBALFAILURE\n"); - Manager::instance().displayError(" !EXOSIP Call Message not implemented yet"); break; case EXOSIP_CALL_CLOSED: /** 25 < a BYE was received for this call */ @@ -367,23 +359,18 @@ SIPVoIPLink::getEvent() break; case EXOSIP_MESSAGE_REDIRECTED: /** 30 < announce a failure. */ _debugMid(" !EXOSIP_MESSAGE_REDIRECTED\n"); - Manager::instance().displayError(" !EXOSIP Message not implemented yet"); break; case EXOSIP_MESSAGE_REQUESTFAILURE: /** 31 < announce a failure. */ _debugMid(" !EXOSIP_MESSAGE_REQUESTFAILURE\n"); - if (event->response !=0 && event->response->status_code == SIP_METHOD_NOT_ALLOWED) { + if (event->response !=0 && event->response->status_code == SIP_METHOD_NOT_ALLOWED) Manager::instance().incomingMessage(getAccountID(), "Message are not allowed"); - } else { - Manager::instance().displayError(" !EXOSIP_MESSAGE_REQUESTFAILURE not implemented yet"); - } break; case EXOSIP_MESSAGE_SERVERFAILURE: /** 32 < announce a failure. */ _debugMid(" !EXOSIP_MESSAGE_SERVERFAILURE\n"); break; case EXOSIP_MESSAGE_GLOBALFAILURE: /** 33 < announce a failure. */ _debugMid(" !EXOSIP_MESSAGE_GLOBALFAILURE\n"); - Manager::instance().displayError(" !EXOSIP Message not implemented yet"); break; /* Presence and Instant Messaging */ @@ -392,7 +379,6 @@ SIPVoIPLink::getEvent() break; case EXOSIP_SUBSCRIPTION_CLOSED: /** 35 < announce end of subscription. */ _debugMid(" !EXOSIP_SUBSCRIPTION_CLOSED\n"); - Manager::instance().displayError(" !EXOSIP Subscription not implemented yet"); break; case EXOSIP_SUBSCRIPTION_NOANSWER: /** 37 < announce no answer */ @@ -400,7 +386,6 @@ SIPVoIPLink::getEvent() break; case EXOSIP_SUBSCRIPTION_PROCEEDING: /** 38 < announce a 1xx */ _debugMid(" !EXOSIP_SUBSCRIPTION_PROCEEDING\n"); - Manager::instance().displayError(" !EXOSIP Subscription response not implemented yet"); break; case EXOSIP_SUBSCRIPTION_ANSWERED: /** 39 < announce a 200ok */ _debugMid(" !EXOSIP_SUBSCRIPTION_ANSWERED\n"); @@ -435,7 +420,6 @@ SIPVoIPLink::getEvent() break; case EXOSIP_SUBSCRIPTION_RELEASED: /** 45 < call context is cleared. */ _debugMid(" !EXOSIP_SUBSCRIPTION_RELEASED\n"); - Manager::instance().displayError(" !EXOSIP Subscription response not implemented yet."); break; case EXOSIP_IN_SUBSCRIPTION_NEW: /** 46 < announce new incoming SUBSCRIBE.*/ @@ -443,7 +427,6 @@ SIPVoIPLink::getEvent() break; case EXOSIP_IN_SUBSCRIPTION_RELEASED: /** 47 < announce end of subscription. */ _debugMid(" !EXOSIP_IN_SUBSCRIPTION_RELEASED\n"); - Manager::instance().displayError(" !EXOSIP Subscription not implemented yet"); break; case EXOSIP_EVENT_COUNT: /** 48 < MAX number of events */ @@ -461,19 +444,15 @@ SIPVoIPLink::sendRegister() { if (_eXosipRegID != EXOSIP_ERROR_STD) { - _debug("nlvnslvnlsnvaljsdnvjlasnvlsfvbnnns sjvlsvn\n"); - Manager::instance().displayError("! SIP Error: Registration already sent. Try to unregister"); return false; } std::string hostname = getHostName(); if (hostname.empty()) { - Manager::instance().displayConfigError("Fill host part field"); return false; } if (_userpart.empty()) { - Manager::instance().displayConfigError("Fill user part field"); return false; } @@ -531,12 +510,6 @@ SIPVoIPLink::SIPFromHeader(const std::string& userpart, const std::string& hostp return ("\"" + getFullName() + "\"" + " <sip:" + userpart + "@" + hostpart + ">"); } -std::string -SIPVoIPLink::SIPFromHeaderAlternate(const std::string& userpart, const std::string& hostpart) -{ - return ("<sip:" + userpart + "@" + hostpart + ">"); -} - bool SIPVoIPLink::sendSIPAuthentification() { @@ -546,12 +519,10 @@ SIPVoIPLink::sendSIPAuthentification() } if (login.empty()) { /** @todo Ajouter ici un call à setRegistrationState(Error, "Fill balh") ? */ - Manager::instance().displayConfigError("Fill authentification name"); return false; } if (_password.empty()) { /** @todo Même chose ici ? */ - Manager::instance().displayConfigError("Fill password field"); return false; } eXosip_lock(); @@ -942,11 +913,9 @@ SIPVoIPLink::sendMessage(const std::string& to, const std::string& body) std::string sipRoute = getSipRoute(); if (!SIPCheckUrl(sipFrom)) { - Manager::instance().displayConfigError("Error in source address"); return returnValue; } if (!SIPCheckUrl(sipTo)) { - Manager::instance().displayError("Error in destination address"); return returnValue; } @@ -1085,11 +1054,9 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject) if (!SIPCheckUrl(from)) { _debug("! SIP Error: Source address is invalid %s\n", from.data()); - Manager::instance().displayConfigError("Error in source address"); return false; } if (!SIPCheckUrl(to)) { - Manager::instance().displayErrorText(call->getCallId(), "Error in destination address"); return false; } @@ -1177,9 +1144,6 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject) return true; } -/** - * Get the Sip FROM url (add sip:, add @host, etc...) - */ std::string SIPVoIPLink::getSipFrom() { @@ -1191,9 +1155,6 @@ SIPVoIPLink::getSipFrom() { return SIPFromHeader(_userpart, host); } -/** - * Get the Sip TO url (add sip:, add @host, etc...) - */ std::string SIPVoIPLink::getSipTo(const std::string& to_url) { // Form the From header field basis on configuration panel @@ -1209,10 +1170,6 @@ SIPVoIPLink::getSipTo(const std::string& to_url) { return SIPToHeader(to_url); } -/** - * Get the sip proxy (add sip: if there is one) - * @return empty string or <sip:proxy;lr> url - */ std::string SIPVoIPLink::getSipRoute() { std::string proxy = _proxy; @@ -1409,7 +1366,6 @@ SIPVoIPLink::SIPCallRequestFailure(eXosip_event_t *event) CallID& id = call->getCallId(); call->setConnectionState(Call::Connected); call->setState(Call::Busy); - Manager::instance().displayErrorText(id, event->response->reason_phrase); Manager::instance().callBusy(id); removeCall(id); } @@ -1430,13 +1386,11 @@ SIPVoIPLink::SIPCallRequestFailure(eXosip_event_t *event) case SIP_NOT_ACCEPTABLE_HERE: // 488 */ // Display error on the screen phone { - _debug("--------------------------------------------------------------error message: %s\n", event->response->reason_phrase); SIPCall* call = findSIPCallWithCid(event->cid); if (call!=0) { CallID& id = call->getCallId(); call->setConnectionState(Call::Connected); call->setState(Call::Error); - Manager::instance().displayErrorText(id, event->response->reason_phrase); Manager::instance().callFailure(id); removeCall(id); } @@ -1610,11 +1564,7 @@ SIPVoIPLink::SIPMessageNew(eXosip_event_t *event) if (msgVoicemail != 0) { // If there is at least one voice-message, start notification Manager::instance().startVoiceMessageNotification(getAccountID(), nb_msg); - } else { - // Stop notification when there is 0 voice message - Manager::instance().stopVoiceMessageNotification(getAccountID()); } - // http://www.jdrosen.net/papers/draft-ietf-simple-im-session-00.txt } else if (MSG_IS_MESSAGE(event->request)) { _debug("> MESSAGE received\n"); @@ -1697,10 +1647,6 @@ SIPVoIPLink::getSIPCall(const CallID& id) return NULL; } -/** - * Handle an INFO with application/dtmf-relay content-type - * @param event eXosip Event - */ bool SIPVoIPLink::handleDtmfRelay(eXosip_event_t* event) { diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h index 25490c9d5856a67afac6a7dc6c7a34c877bdcc80..a62aa7b9297c7ec7a35d9a472ddba88b8d2a3a60 100644 --- a/src/sipvoiplink.h +++ b/src/sipvoiplink.h @@ -1,7 +1,8 @@ /* - * Copyright (C) 2004-2006 Savoir-Faire Linux inc. + * Copyright (C) 2004-2008 Savoir-Faire Linux inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.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 @@ -30,263 +31,413 @@ class EventThread; class SIPCall; /** - * Specific VoIPLink for SIP (SIP core for incoming and outgoing events) + * @file sipvoiplink.h + * @brief Specific VoIPLink for SIP (SIP core for incoming and outgoing events) */ class SIPVoIPLink : public VoIPLink { -public: - SIPVoIPLink(const AccountID& accountID); - - ~SIPVoIPLink(); - - int eXosip_running; - - /** try to initiate the eXosip engine/thread and set config */ - bool init(void); - void terminate(void); - bool checkNetwork(void); - void getEvent(void); - - bool sendRegister(void); - bool sendUnregister(void); - - Call* newOutgoingCall(const CallID& id, const std::string& toUrl); - bool answer(const CallID& id); - - bool hangup(const CallID& id); - bool cancel(const CallID& id); - bool onhold(const CallID& id); - bool offhold(const CallID& id); - bool transfer(const CallID& id, const std::string& to); - bool refuse (const CallID& id); - bool carryingDTMFdigits(const CallID& id, char code); - bool sendMessage(const std::string& to, const std::string& body); - bool isContactPresenceSupported(); - void subscribePresenceForContact(Contact* contact); - void publishPresenceStatus(std::string status); - - // TODO Not used yet - void sendMessageToContact(const CallID& id, const std::string& message); - - // SIP Specific - - /** If set to true, we check for a firewall - * @param use true if we use STUN - */ - void setUseStun(bool use) { _useStun = use; } - - /** The name of the STUN server - * @param server Server FQDN/IP - */ - void setStunServer(const std::string& server) { _stunServer = server; } - - /** Set the SIP proxy - * @param proxy Proxy FQDN/IP - */ - void setProxy(const std::string& proxy) { _proxy = proxy; } - void setUserPart(const std::string& userpart) { _userpart = userpart; } - void setAuthName(const std::string& authname) { _authname = authname; } - void setPassword(const std::string& password) { _password = password; } - - -private: - void parseRequestUri( osip_uri_t* ); - /** Terminate every call not hangup | brutal | Protected by mutex */ - void terminateSIPCall(); - - /** - * Get the local Ip by eXosip - * only if the local ip address is to his default value: 127.0.0.1 - * setLocalIpAdress - * @return false if not found - */ - bool loadSIPLocalIP(); - - /** - * send SIP authentification - * @return true if sending succeed - */ - bool sendSIPAuthentification(); - - /** - * Get a SIP From header ("fullname" <sip:userpart@hostpart>) - * @param userpart - * @param hostpart - * @return SIP URI for from Header - */ - std::string SIPFromHeader(const std::string& userpart, const std::string& hostpart); - std::string SIPFromHeaderAlternate(const std::string& userpart, const std::string& hostpart); - - /** - * Build a sip address with the number that you want to call - * Example: sip:124@domain.com - * @return result as a string - */ - std::string SIPToHeader(const std::string& to); - - /** - * Check if an url is sip-valid - * @return true if osip tell that is valid - */ - bool SIPCheckUrl(const std::string& url); - - - /** - * SIPOutgoingInvite do SIPStartCall - * @return true if all is correct - */ - bool SIPOutgoingInvite(SIPCall* call); - - /** - * Start a SIP Call - * @return true if all is correct - */ - bool SIPStartCall(SIPCall* call, const std::string& subject); - std::string getSipFrom(); - std::string getSipRoute(); - std::string getSipTo(const std::string& to_url); - - /** - * Set audio (SDP) configuration for a call - * localport, localip, localexternalport - * @param call a SIPCall valid pointer - * @return true - */ - bool setCallAudioLocal(SIPCall* call); - - /** - * Create a new call and send a incoming call notification to the user - * @param event eXosip Event - */ - void SIPCallInvite(eXosip_event_t *event); - - /** - * Use a exisiting call to restart the audio - * @param event eXosip Event - */ - void SIPCallReinvite(eXosip_event_t *event); - - /** - * Tell the user that the call is ringing - * @param event eXosip Event - */ - void SIPCallRinging(eXosip_event_t *event); - - /** - * Tell the user that the call was answered - * @param event eXosip Event - */ - void SIPCallAnswered(eXosip_event_t *event); - - /** - * Handling 4XX error - * @param event eXosip Event - */ - void SIPCallRequestFailure(eXosip_event_t *event); - - /** - * Handling 5XX/6XX error - * @param event eXosip Event - */ - void SIPCallServerFailure(eXosip_event_t *event); - - void SIPRegistrationFailure( eXosip_event_t *event ); - /** - * Handling ack (restart audio if reinvite) - * @param event eXosip Event - */ - void SIPCallAck(eXosip_event_t *event); - - /** - * Handling message inside a call (like dtmf) - * @param event eXosip Event - */ - void SIPCallMessageNew(eXosip_event_t *event); - bool handleDtmfRelay(eXosip_event_t *event); - - /** - * Peer close the connection - * @param event eXosip Event - */ - void SIPCallClosed(eXosip_event_t *event); - - /** - * The call pointer was released - * If the call was not cleared before, report an error - * @param event eXosip Event - */ - void SIPCallReleased(eXosip_event_t *event); - - /** - * Receive a new Message request - * Option/Notify/Message - * @param event eXosip Event - */ - void SIPMessageNew(eXosip_event_t *event); - - /** - * Find a SIPCall with cid from eXosip Event - * Explication there is no DID when the dialog is not establish... - * @param cid call ID - * @return 0 or SIPCall pointer - */ - SIPCall* findSIPCallWithCid(int cid); - - /** - * Find a SIPCall with cid and did from eXosip Event - * @param cid call ID - * @param did domain ID - * @return 0 or SIPCall pointer - */ - SIPCall* findSIPCallWithCidDid(int cid, int did); - SIPCall* getSIPCall(const CallID& id); - - /** To build sdp when call is on-hold */ - int sdp_hold_call (sdp_message_t * sdp); - /** To build sdp when call is off-hold */ - int sdp_off_hold_call (sdp_message_t * sdp); - - /** EventThread get every incoming events */ - EventThread* _evThread; - /** Tell if eXosip was stared (eXosip_init) */ - bool _initDone; - - /** Registration identifier, needed by unregister to build message */ - int _eXosipRegID; - - /** Number of voicemail */ - int _nMsgVoicemail; - - /** when we init the listener, how many times we try to bind a port? */ - int _nbTryListenAddr; - - /** Do we use stun? */ - bool _useStun; - - /** What is the stun server? */ - std::string _stunServer; - - /** Local Extern Address is the IP address seen by peers for SIP listener */ - std::string _localExternAddress; - - /** Local Extern Port is the port seen by peers for SIP listener */ - unsigned int _localExternPort; - - /** SIP Proxy URL */ - std::string _proxy; - - /** SIP UserPart */ - std::string _userpart; - - /** SIP Authenfication name */ - std::string _authname; - - /** SIP Authenfication password */ - std::string _password; - - /** Starting sound */ - AudioRtp _audiortp; + public: + + /** + * Constructor + * @param accountID The account identifier + */ + SIPVoIPLink(const AccountID& accountID); + + /** + * Destructor + */ + ~SIPVoIPLink(); + + int eXosip_running; + + /** + * Try to initiate the eXosip engine/thread and set config + * @return bool True if OK + */ + bool init(void); + + /** + * Delete link-related stuuf like calls + */ + void terminate(void); + + /** + * Check if a local IP can be found + * @return bool True if network is reachable + */ + bool checkNetwork(void); + + /** + * Event listener. Each event send by the call manager is received and handled from here + */ + void getEvent(void); + + /** + * Build and send SIP registration request + * @return bool True on success + * false otherwise + */ + bool sendRegister(void); + + /** + * Build and send SIP unregistration request + * @return bool True on success + * false otherwise + */ + bool sendUnregister(void); + + /** + * Place a new call + * @param id The call identifier + * @param toUrl The Sip address of the recipient of the call + * @return Call* The current call + */ + Call* newOutgoingCall(const CallID& id, const std::string& toUrl); + + /** + * Answer the call + * @param id The call identifier + * @return bool True on success + */ + bool answer(const CallID& id); + + /** + * Hang up the call + * @param id The call identifier + * @return bool True on success + */ + bool hangup(const CallID& id); + + /** + * Cancel the call + * @param id The call identifier + * @return bool True on success + */ + bool cancel(const CallID& id); + + /** + * Put the call on hold + * @param id The call identifier + * @return bool True on success + */ + bool onhold(const CallID& id); + + /** + * Put the call off hold + * @param id The call identifier + * @return bool True on success + */ + bool offhold(const CallID& id); + + /** + * Transfer the call + * @param id The call identifier + * @param to The recipient of the transfer + * @return bool True on success + */ + bool transfer(const CallID& id, const std::string& to); + + /** + * Refuse the call + * @param id The call identifier + * @return bool True on success + */ + bool refuse (const CallID& id); + + /** + * Send DTMF + * @param id The call identifier + * @param code The char code + * @return bool True on success + */ + bool carryingDTMFdigits(const CallID& id, char code); + + bool sendMessage(const std::string& to, const std::string& body); + + bool isContactPresenceSupported(); + + void subscribePresenceForContact(Contact* contact); + + void publishPresenceStatus(std::string status); + + // TODO Not used yet + void sendMessageToContact(const CallID& id, const std::string& message); + + /** + * If set to true, we check for a firewall + * @param use true if we use STUN + */ + void setUseStun(bool use) { _useStun = use; } + + /** + * The name of the STUN server + * @param server Server FQDN/IP + */ + void setStunServer(const std::string& server) { _stunServer = server; } + + /** + * Set the SIP proxy + * @param proxy Proxy FQDN/IP + */ + void setProxy(const std::string& proxy) { _proxy = proxy; } + + /** + * Set the user part + * @param userpart User part + */ + void setUserPart(const std::string& userpart) { _userpart = userpart; } + + /** + * Set the authentification name + * @param authname The authentification name + */ + void setAuthName(const std::string& authname) { _authname = authname; } + + /** + * Set the password + * @param password Password + */ + void setPassword(const std::string& password) { _password = password; } + + private: + + /** + * Terminate every call not hangup | brutal | Protected by mutex + */ + void terminateSIPCall(); + + /** + * Get the local Ip by eXosip + * only if the local ip address is to his default value: 127.0.0.1 + * setLocalIpAdress + * @return bool false if not found + */ + bool loadSIPLocalIP(); + + /** + * send SIP authentification + * @return bool true if sending succeed + */ + bool sendSIPAuthentification(); + + /** + * Get a SIP From header ("fullname" <sip:userpart@hostpart>) + * @param userpart User part + * @param hostpart Host name + * @return std::string SIP URI for from Header + */ + std::string SIPFromHeader(const std::string& userpart, const std::string& hostpart); + + /** + * Build a sip address with the number that you want to call + * Example: sip:124@domain.com + * @param to The header of the recipient + * @return std::string Result as a string + */ + std::string SIPToHeader(const std::string& to); + + /** + * Check if an url is sip-valid + * @param url The url to check + * @return bool True if osip tell that is valid + */ + bool SIPCheckUrl(const std::string& url); + + + /** + * Send an outgoing call invite + * @param call The current call + * @return bool True if all is correct + */ + bool SIPOutgoingInvite(SIPCall* call); + + /** + * Start a SIP Call + * @param call The current call + * @param subject Undocumented + * @return true if all is correct + */ + bool SIPStartCall(SIPCall* call, const std::string& subject); + + /** + * Get the Sip FROM url (add sip:, add @host, etc...) + * @return std::string The From url + */ + std::string getSipFrom(); + + /** + * Get the sip proxy (add sip: if there is one) + * @return std::string Empty string or <sip:proxy;lr> url + */ + std::string getSipRoute(); + + /** + * Get the Sip TO url (add sip:, add @host, etc...) + * @param to_url The To url + * @return std::string The SIP to address + */ + std::string getSipTo(const std::string& to_url); + + /** + * Set audio (SDP) configuration for a call + * localport, localip, localexternalport + * @param call a SIPCall valid pointer + * @return bool True + */ + bool setCallAudioLocal(SIPCall* call); + + /** + * Create a new call and send a incoming call notification to the user + * @param event eXosip Event + */ + void SIPCallInvite(eXosip_event_t *event); + + /** + * Use a exisiting call to restart the audio + * @param event eXosip Event + */ + void SIPCallReinvite(eXosip_event_t *event); + + /** + * Tell the user that the call is ringing + * @param event eXosip Event + */ + void SIPCallRinging(eXosip_event_t *event); + + /** + * Tell the user that the call was answered + * @param event eXosip Event + */ + void SIPCallAnswered(eXosip_event_t *event); + + /** + * Handling 4XX error + * @param event eXosip Event + */ + void SIPCallRequestFailure(eXosip_event_t *event); + + /** + * Handling 5XX/6XX error + * @param event eXosip Event + */ + void SIPCallServerFailure(eXosip_event_t *event); + + /** + * Handle registration failure cases ( SIP_FORBIDDEN , SIP_UNAUTHORIZED ) + * @param event eXosip event + */ + void SIPRegistrationFailure( eXosip_event_t *event ); + + /** + * Handling ack (restart audio if reinvite) + * @param event eXosip Event + */ + void SIPCallAck(eXosip_event_t *event); + + /** + * Handling message inside a call (like dtmf) + * @param event eXosip Event + */ + void SIPCallMessageNew(eXosip_event_t *event); + + /** + * Handle an INFO with application/dtmf-relay content-type + * @param event eXosip Event + */ + bool handleDtmfRelay(eXosip_event_t *event); + + /** + * Peer close the connection + * @param event eXosip Event + */ + void SIPCallClosed(eXosip_event_t *event); + + /** + * The call pointer was released + * If the call was not cleared before, report an error + * @param event eXosip Event + */ + void SIPCallReleased(eXosip_event_t *event); + + /** + * Receive a new Message request + * Option/Notify/Message + * @param event eXosip Event + */ + void SIPMessageNew(eXosip_event_t *event); + + /** + * Find a SIPCall with cid from eXosip Event + * Explication there is no DID when the dialog is not establish... + * @param cid call ID + * @return SIPCall* SIPCall pointer or 0 + */ + SIPCall* findSIPCallWithCid(int cid); + + /** + * Find a SIPCall with cid and did from eXosip Event + * @param cid call ID + * @param did domain ID + * @return SIPCall* SIPCall pointer or 0 + */ + SIPCall* findSIPCallWithCidDid(int cid, int did); + + /** + * SIPCall accessor + * @param id The call identifier + * @return SIPCall* A pointer on SIPCall object + */ + SIPCall* getSIPCall(const CallID& id); + + /** To build sdp when call is on-hold */ + int sdp_hold_call (sdp_message_t * sdp); + + /** To build sdp when call is off-hold */ + int sdp_off_hold_call (sdp_message_t * sdp); + + /** EventThread get every incoming events */ + EventThread* _evThread; + + /** Tell if eXosip was stared (eXosip_init) */ + bool _initDone; + + /** Registration identifier, needed by unregister to build message */ + int _eXosipRegID; + + /** Number of voicemail */ + int _nMsgVoicemail; + + /** when we init the listener, how many times we try to bind a port? */ + int _nbTryListenAddr; + + /** Do we use stun? */ + bool _useStun; + + /** What is the stun server? */ + std::string _stunServer; + + /** Local Extern Address is the IP address seen by peers for SIP listener */ + std::string _localExternAddress; + + /** Local Extern Port is the port seen by peers for SIP listener */ + unsigned int _localExternPort; + + /** SIP Proxy URL */ + std::string _proxy; + + /** SIP UserPart */ + std::string _userpart; + + /** SIP Authenfication name */ + std::string _authname; + + /** SIP Authenfication password */ + std::string _password; + + /** Starting sound */ + AudioRtp _audiortp; }; #endif diff --git a/src/user_cfg.h b/src/user_cfg.h index bafce381485eb5282879e8b20d37eada4829ba7d..6c94010836b867eeced149c586273b6d81b5ba6d 100644 --- a/src/user_cfg.h +++ b/src/user_cfg.h @@ -1,7 +1,8 @@ /* - * Copyright (C) 2004-2006 Savoir-Faire Linux inc. + * Copyright (C) 2004-2008 Savoir-Faire Linux inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * Authoe: Emmanuel Milou <emmanuel.milou@savoirfairelinux.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 @@ -23,76 +24,63 @@ #include <stdlib.h> -// Home directory -#define HOMEDIR (getenv ("HOME")) +#define HOMEDIR (getenv ("HOME")) /** Home directory */ -// TODO: change for a \ in Windows Environment -#define DIR_SEPARATOR_CH '/' -#define DIR_SEPARATOR_STR "/" +#define DIR_SEPARATOR_CH '/' /** Directory separator string */ +#define DIR_SEPARATOR_STR "/" /** Directory separator char */ -// Main menu -#define SIGNALISATION "VoIPLink" -#define AUDIO "Audio" -#define VIDEO "Video" -#define NETWORK "Network" -#define PREFERENCES "Preferences" +#define ACCOUNT_SIP0 "SIP0" /** Account type SIP */ +#define ACCOUNT_IAX0 "IAX0" /** Account type IAX */ -#define ACCOUNT_SIP0 "SIP0" -#define ACCOUNT_IAX0 "IAX0" +/** User configuration file fields */ +#define AUDIO "Audio" /** Section Audio */ +#define CODECS "ActiveCodecs" /** List of active codecs */ +#define ALSA_CARD_ID_IN "Alsa.cardID_In" /** Soundcard index to use for capture */ +#define ALSA_CARD_ID_OUT "Alsa.cardID_Out" /** Soundcard index to use for playback */ +#define ALSA_FRAME_SIZE "Alsa.framesize" /** Audio layer frame size */ +#define ALSA_PLUGIN "Alsa.plugin" /** Alsa plugin */ +#define ALSA_SAMPLE_RATE "Alsa.sampleRate" /** Audio layer sample rate */ +#define RING_CHOICE "Rings.ringChoice" /** Ringtone */ +#define VOLUME_SPKR "Volume.speakers" /** Speaker volume */ +#define VOLUME_MICRO "Volume.micro" /** Mic volume */ +#define VIDEO "Video" /** Section Video */ -// Fields to fill -#define SYMMETRIC "VoIPLink.symmetric" +#define PREFERENCES "Preferences" /** Section Preferences */ +#define CONFIG_DIALPAD "Dialpad.display" /** Display dialpad preferences */ +#define ZONE_TONE "Options.zoneToneChoice" /** Country tone */ +#define VOICEMAIL_NUM "Options.voicemailNumber" /** Voicemail number */ +#define CONFIG_RINGTONE "Ringtones.enable" /** Ringtones preferences */ +#define CONFIG_START "Start.hidden" /** SFLphone starts in the systm tray or not */ +#define CONFIG_POPUP "Window.popup" /** SFLphone pops up on incoming calls or not */ +#define CONFIG_ZEROCONF "Zeroconf.enable" /** Zero configuration networking module */ -#define PLAY_DTMF "DTMF.playDtmf" -#define PLAY_TONES "DTMF.playTones" -#define PULSE_LENGTH "DTMF.pulseLength" -#define SEND_DTMF_AS "DTMF.sendDTMFas" -#define ALSA_CARD_ID_IN "Alsa.cardID_In" -#define ALSA_CARD_ID_OUT "Alsa.cardID_Out" -#define ALSA_SAMPLE_RATE "Alsa.sampleRate" -#define ALSA_FRAME_SIZE "Alsa.framesize" -#define ALSA_PLUGIN "Alsa.plugin" -#define CODECS "ActiveCodecs" -#define RING_CHOICE "Rings.ringChoice" -#define ACCOUNT_SIP_COUNT_DEFAULT 4 -#define ACCOUNT_IAX_COUNT_DEFAULT 4 +#define SIGNALISATION "VoIPLink" /** Section Signalisation */ +#define PLAY_DTMF "DTMF.playDtmf" /** Whether or not should play dtmf */ +#define PLAY_TONES "DTMF.playTones" /** Whether or not should play tones */ +#define PULSE_LENGTH "DTMF.pulseLength" /** Length of the DTMF in millisecond */ +#define SEND_DTMF_AS "DTMF.sendDTMFas" /** DTMF send mode */ +#define SYMMETRIC "VoIPLink.symmetric" /** VoIP link type */ -// speakers and volume 0 to 100 -#define VOLUME_SPKR "Volume.speakers" -#define VOLUME_MICRO "Volume.micro" -#define ZONE_TONE "Options.zoneToneChoice" -#define VOICEMAIL_NUM "Options.voicemailNumber" -// zeroconfig module -#define CONFIG_ZEROCONF "Zeroconf.enable" -#define CONFIG_RINGTONE "Ringtones.enable" -#define CONFIG_DIALPAD "Dialpad.display" -#define CONFIG_START "Start.hidden" -#define CONFIG_POPUP "Window.popup" +#define EMPTY_FIELD "" /** Default value for empty field */ +#define DFT_STUN_SERVER "stun.fwdnet.net:3478" /** Default STUN server address */ +#define YES_STR "1" /** Default YES value */ +#define NO_STR "0" /** Default NO value */ +#define DFT_PULSE_LENGTH_STR "250" /** Default DTMF lenght */ +#define SIP_INFO_STR "0" /** Default DTMF transport mode */ +#define ALSA_DFT_CARD "0" /** Default sound card index */ +#define DFT_VOL_SPKR_STR "100" /** Default speaker volume */ +#define DFT_VOL_MICRO_STR "100" /** Default mic volume */ +#define DFT_RINGTONE "konga.ul" /** Default ringtone */ +#define DFT_ZONE "North America" /** Default geographical zone */ +#define DFT_VOICEMAIL "888" /** Default voicemail number */ +#define DFT_FRAME_SIZE "20" /** Default frame size in millisecond */ +#define DFT_SAMPLE_RATE "44100" /** Default sample rate in HZ */ -// Default values -#define EMPTY_FIELD "" -#define DFT_STUN_SERVER "stun.fwdnet.net:3478" -#define YES_STR "1" -#define NO_STR "0" -#define DFT_PULSE_LENGTH_STR "250" -#define SIP_INFO_STR "0" -#define ALSA_DFT_CARD "0" -// volume by default 100% -#define DFT_VOL_SPKR_STR "100" -#define DFT_VOL_MICRO_STR "100" - -#define DFT_RINGTONE "konga.ul" -#define DFT_ZONE "North America" -#define DFT_VOICEMAIL "888" -#define DFT_FRAME_SIZE "20" -#define DFT_SAMPLE_RATE "44100" - -// zeroconfig default value #ifdef USE_ZEROCONF -#define CONFIG_ZEROCONF_DEFAULT_STR "1" +#define CONFIG_ZEROCONF_DEFAULT_STR "1" /** Default Zero configuration networking module value */ #else -#define CONFIG_ZEROCONF_DEFAULT_STR "0" +#define CONFIG_ZEROCONF_DEFAULT_STR "0" /** Default Zero configuration networking module value */ #endif #endif // __USER_CFG_H__ diff --git a/src/voiplink.h b/src/voiplink.h index ad7ee15a7e054d35f1a1a6932de3849a2c603fab..4f4672e73e69af1cd87ea51edff18289cdb5e643 100644 --- a/src/voiplink.h +++ b/src/voiplink.h @@ -30,195 +30,290 @@ class AudioCodec; -//#include "account.h" // for AccountID -// replaced by: +/** Define AccountID type */ typedef std::string AccountID; +/** Define a map that associate a Call object to a call identifier */ typedef std::map<CallID, Call*> CallMap; /** - * Listener and manager interface for each VoIP protocol + * @file voiplink.h + * @brief Listener and manager interface for each VoIP protocol */ class VoIPLink { -public: - VoIPLink(const AccountID& accountID); - virtual ~VoIPLink (void); - - enum RegistrationState {Unregistered, Trying, Registered, Error, ErrorAuth , ErrorNetwork , ErrorHost}; - - // Pure virtual functions - virtual void getEvent (void) = 0; - virtual bool init (void) = 0; - virtual bool checkNetwork (void) = 0; - virtual void terminate (void) = 0; - virtual bool sendRegister (void) = 0; - virtual bool sendUnregister (void) = 0; - - /** Add a new outgoing call and return the call pointer or 0 if and error occurs */ - virtual Call* newOutgoingCall(const CallID& id, const std::string& toUrl) = 0; - virtual bool answer(const CallID& id) = 0; - - /** - * Hang up a call - */ - virtual bool hangup(const CallID& id) = 0; - - /** - * Cancel the call dialing - */ - virtual bool cancel(const CallID& id) = 0; - - /** - * Put a call on hold - */ - virtual bool onhold(const CallID& id) = 0; - - /** - * Resume a call from hold state - */ - virtual bool offhold(const CallID& id) = 0; - - /** - * Transfer a call to specified URI - */ - virtual bool transfer(const CallID& id, const std::string& to) = 0; - - /** - * Refuse incoming call - */ - virtual bool refuse(const CallID& id) = 0; - - virtual bool carryingDTMFdigits(const CallID& id, char code) = 0; - - /** - * Send text message - */ - virtual bool sendMessage(const std::string& to, const std::string& body) = 0; - - // NOW - /** - * Determine if link supports presence information - */ - virtual bool isContactPresenceSupported() = 0; - - /** - * Register contacts for presence information if supported - */ - virtual void subscribePresenceForContact(Contact* contact); - - /** - * Publish presence status to server - */ - virtual void publishPresenceStatus(std::string status); - - // these method are set only with 'Account init' and can be get by everyone - void setFullName (const std::string& fullname) { _fullname = fullname; } - std::string& getFullName (void) { return _fullname; } - void setHostName (const std::string& hostname) { _hostname = hostname; } - std::string& getHostName (void) { return _hostname; } - - /** - * Return parent Account's ID - */ - AccountID& getAccountID(void) { return _accountID; } - - /** - * Set parent Account's ID - */ - void setAccountID( const AccountID& accountID) { _accountID = accountID; } - - /** Get the call pointer from the call map (protected by mutex) - * @param id A Call ID - * @return call pointer or 0 - */ - Call* getCall(const CallID& id); - - /** - * Get registration state - */ - enum RegistrationState getRegistrationState() { return _registrationState; } - - /** - * Get registration error message, if set. - */ - int getRegistrationError() { return _registrationError; } - - /** - * Set new registration state - * - * We use this function, in case the server needs to PUSH to the - * GUI when the state changes. - */ - void setRegistrationState(const enum RegistrationState state, - const int& errorCode); - - /** - * Same, but with default error value to "" - */ - void setRegistrationState(const enum RegistrationState state); - -private: - /** - * Full name used as outgoing Caller ID - */ - std::string _fullname; - - /** - * Host name used for authentication - */ - std::string _hostname; - - /** - * ID of parent's Account - */ - AccountID _accountID; - - /** - * State of registration - */ - enum RegistrationState _registrationState; - - /** - * Registration error code -> refers to global.h - */ - int _registrationError; - -protected: - /** Add a call to the call map (protected by mutex) - * @param call A call pointer with a unique pointer - * @return true if the call was unique and added - */ - bool addCall(Call* call); - - /** Remove a call from the call map (protected by mutex) - * @param id A Call ID - * @return true if the call was correctly removed - */ - bool removeCall(const CallID& id); - - /** - * Remove all the call from the map - */ - bool clearCallMap(); - - /** Contains all the calls for this Link, protected by mutex */ - CallMap _callMap; - - /** Mutex to protect call map */ - ost::Mutex _callMapMutex; - - /** Get Local IP Address (ie: 127.0.0.1, 192.168.0.1, ...) */ - std::string _localIPAddress; - /** Get local listening port (5060 for SIP, ...) */ - unsigned int _localPort; - - - /** Whether init() was called already or not - * - * This should be used in [IAX|SIP]VoIPLink::init() and terminate(), to - * indicate that init() was called, or reset by terminate(). - */ - bool _initDone; + public: + + /** + * Constructor + * @param accountID The account identifier + */ + VoIPLink(const AccountID& accountID); + + /** + * Virtual destructor + */ + virtual ~VoIPLink (void); + + /** Contains all the state an Voip can be in */ + enum RegistrationState {Unregistered, Trying, Registered, Error, ErrorAuth , ErrorNetwork , ErrorHost}; + + /** + * Virtual method + * Event listener. Each event send by the call manager is received and handled from here + */ + virtual void getEvent (void) = 0; + + /** + * Virtual method + * Try to initiate the eXosip engine/thread and set config + * @return bool True if OK + */ + virtual bool init (void) = 0; + + /** + * Virtual method + * Check if a local IP can be found + * @return bool True if network is reachable + */ + virtual bool checkNetwork (void) = 0; + + /** + * Virtual method + * Delete link-related stuuf like calls + */ + virtual void terminate (void) = 0; + + /** + * Virtual method + * Build and send SIP registration request + * @return bool True on success + * false otherwise + */ + virtual bool sendRegister (void) = 0; + + /** + * Virtual method + * Build and send SIP unregistration request + * @return bool True on success + * false otherwise + */ + virtual bool sendUnregister (void) = 0; + + /** + * Place a new call + * @param id The call identifier + * @param toUrl The Sip address of the recipient of the call + * @return Call* The current call + */ + virtual Call* newOutgoingCall(const CallID& id, const std::string& toUrl) = 0; + /** + * Answer the call + * @param id The call identifier + * @return bool True on success + */ + virtual bool answer(const CallID& id) = 0; + + /** + * Hang up a call + * @param id The call identifier + * @return bool True on success + */ + virtual bool hangup(const CallID& id) = 0; + + /** + * Cancel the call dialing + * @param id The call identifier + * @return bool True on success + */ + virtual bool cancel(const CallID& id) = 0; + + /** + * Put a call on hold + * @param id The call identifier + * @return bool True on success + */ + virtual bool onhold(const CallID& id) = 0; + + /** + * Resume a call from hold state + * @param id The call identifier + * @return bool True on success + */ + virtual bool offhold(const CallID& id) = 0; + + /** + * Transfer a call to specified URI + * @param id The call identifier + * @param to The recipient of the call + * @return bool True on success + */ + virtual bool transfer(const CallID& id, const std::string& to) = 0; + + /** + * Refuse incoming call + * @param id The call identifier + * @return bool True on success + */ + virtual bool refuse(const CallID& id) = 0; + + /** + * Send DTMF + * @param id The call identifier + * @param code The char code + * @return bool True on success + */ + virtual bool carryingDTMFdigits(const CallID& id, char code) = 0; + + /** + * Send text message + */ + virtual bool sendMessage(const std::string& to, const std::string& body) = 0; + + // NOW + /** + * Determine if link supports presence information + */ + virtual bool isContactPresenceSupported() = 0; + + /** + * Register contacts for presence information if supported + */ + virtual void subscribePresenceForContact(Contact* contact); + + /** + * Publish presence status to server + */ + virtual void publishPresenceStatus(std::string status); + + /** + * Set the account full name + * @param fullname The full name + */ + void setFullName (const std::string& fullname) { _fullname = fullname; } + + /** + * Get the account full name + * @return std::string The full name + */ + std::string& getFullName (void) { return _fullname; } + + /** + * Set the account host name + * @param hostname The host name + */ + void setHostName (const std::string& hostname) { _hostname = hostname; } + + /** + * Get the account host name + * @return std::string The host name + */ + std::string& getHostName (void) { return _hostname; } + + /** + * @return AccountID parent Account's ID + */ + AccountID& getAccountID(void) { return _accountID; } + + /** + * @param accountID The account identifier + */ + void setAccountID( const AccountID& accountID) { _accountID = accountID; } + + /** Get the call pointer from the call map (protected by mutex) + * @param id A Call ID + * @return Call* Call pointer or 0 + */ + Call* getCall(const CallID& id); + + /** + * Get registration state + * @return RegistrationState + */ + enum RegistrationState getRegistrationState() { return _registrationState; } + + /** + * Get registration error message, if set. + */ + int getRegistrationError() { return _registrationError; } + + /** + * Set new registration state + * We use this function, in case the server needs to PUSH to the + * GUI when the state changes. + * @param state The registration state + * @param errorCode The error code + */ + void setRegistrationState(const enum RegistrationState state, + const int& errorCode); + + /** + * Set new registration state + * @param state The registration state + */ + void setRegistrationState(const enum RegistrationState state); + + private: + /** + * Full name used as outgoing Caller ID + */ + std::string _fullname; + + /** + * Host name used for authentication + */ + std::string _hostname; + + /** + * ID of parent's Account + */ + AccountID _accountID; + + /** + * State of registration + */ + enum RegistrationState _registrationState; + + /** + * Registration error code -> refers to global.h + */ + int _registrationError; + + protected: + /** Add a call to the call map (protected by mutex) + * @param call A call pointer with a unique pointer + * @return bool True if the call was unique and added + */ + bool addCall(Call* call); + + /** Remove a call from the call map (protected by mutex) + * @param id A Call ID + * @return bool True if the call was correctly removed + */ + bool removeCall(const CallID& id); + + /** + * Remove all the call from the map + * @return bool True on success + */ + bool clearCallMap(); + + /** Contains all the calls for this Link, protected by mutex */ + CallMap _callMap; + + /** Mutex to protect call map */ + ost::Mutex _callMapMutex; + + /** Get Local IP Address (ie: 127.0.0.1, 192.168.0.1, ...) */ + std::string _localIPAddress; + + /** Get local listening port (5060 for SIP, ...) */ + unsigned int _localPort; + + /** Whether init() was called already or not + * This should be used in [IAX|SIP]VoIPLink::init() and terminate(), to + * indicate that init() was called, or reset by terminate(). + */ + bool _initDone; }; #endif // __VOIP_LINK_H__