diff --git a/src/account.cpp b/src/account.cpp index 5bc6ba36ebb8325da825c8e93d3e1fdfa30dc1a7..cb2d710a750c9a1da5229683608e6f289f4aece5 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -22,9 +22,10 @@ #include "account.h" #include "manager.h" -Account::Account(const AccountID& accountID) : - _accountID(accountID), _link(NULL), _enabled(false) +Account::Account(const AccountID& accountID, std::string type) : + _accountID(accountID), _link(NULL), _enabled(false), _type(type) { + setRegistrationState(VoIPLink::Unregistered); } Account::~Account() diff --git a/src/account.h b/src/account.h index 571f7220315facc986953b1c7a9cc9a2cb2f7b89..a71ffd775e31038c45a4fbead66696a4e4ec866b 100644 --- a/src/account.h +++ b/src/account.h @@ -38,6 +38,19 @@ class VoIPLink; typedef std::string AccountID; +/** Contains all the state an Voip can be in */ + typedef enum RegistrationState { + Unregistered, + Trying, + Registered, + Error, + ErrorAuth , + ErrorNetwork , + ErrorHost, + ErrorExistStun, + ErrorConfStun + } RegistrationState; + #define AccountNULL "" // Common account parameters @@ -59,7 +72,7 @@ class Account{ public: - Account(const AccountID& accountID); + Account(const AccountID& accountID, std::string type); /** * Virtual destructor @@ -106,10 +119,31 @@ class Account{ * Get the registration state of the specified link * @return RegistrationState The registration state of underlying VoIPLink */ - VoIPLink::RegistrationState getRegistrationState() { return _link->getRegistrationState(); } + inline RegistrationState getRegistrationState() { return _registrationState; } - private: + inline void setRegistrationState( RegistrationState state ) { + _registrationState = state; + + // Notify the client + Manager::instance().connectionStatusNotification( ); + } + + inline std::string getUsername( void ) { return _username; } + inline void setUsername( std::string username) { _username = username; } + + inline std::string getHostname( void ) { return _hostname; } + inline void setHostname( std::string hostname) { _hostname = hostname; } + + inline std::string getPassword( void ) { return _password; } + inline void setPassword( std::string password ) { _password = password; } + + inline std::string getAlias( void ) { return _alias; } + inline void setAlias( std::string alias ) { _alias = alias; } + inline std::string getType( void ) { return _type; } + inline void setType( std::string type ) { _type = type; } + + private: // copy constructor Account(const Account& rh); @@ -122,6 +156,32 @@ class Account{ */ AccountID _accountID; + /** + * Account login information: username + */ + std::string _username; + + /** + * Account login information: hostname + */ + std::string _hostname; + + /** + * Account login information: password + */ + std::string _password; + + /** + * Account login information: Alias + */ + std::string _alias; + + /* + * The account type + * IAX2 or SIP + */ + std::string _type; + /** * Voice over IP Link contains a listener thread and calls */ @@ -134,6 +194,11 @@ class Account{ */ bool _enabled; + /* + * The registration state of the account + */ + RegistrationState _registrationState; + }; #endif diff --git a/src/eventthread.cpp b/src/eventthread.cpp index e7103908a6b2e8df05d0528c37c1cb1936b1a88e..d141505e7e6c04ba4c0301ec921390d7fbb163a0 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -20,31 +20,22 @@ #include "eventthread.h" #include "voiplink.h" -/********************************** IAX Voiplink thread *************************************/ -/** - * Reimplementation of run() - */ -void IAXEventThread::run (void) +/********************************** Voiplink thread *************************************/ +EventThread::EventThread( VoIPLink *link ) + : Thread(), _linkthread(link) { - while(!testCancel()) { - _linkthread->getEvent(); - } -} - -/********************************************************************************************/ - + setCancel( cancelDeferred ); +} -/********************************** SIP Voiplink thread *************************************/ /** * Reimplementation of run() */ -void SIPEventThread::run (void) - +void EventThread::run (void) { while(!testCancel()) { _linkthread->getEvent(); } -} +} /********************************************************************************************/ diff --git a/src/eventthread.h b/src/eventthread.h index f09afb016fc20c2de26ba9098de7987f1a7b2d67..0d43a18d716f685388ebddec29e7e4edeb52abe2 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -31,23 +31,17 @@ class VoIPLink; class EventThread : public ost::Thread { - friend class SIPEventThread; - friend class IAXEventThread; - public: /** * Thread constructor */ - EventThread (VoIPLink* link) : Thread(), _linkthread(link){ - setCancel( cancelDeferred ); - } + EventThread (VoIPLink* link); - - virtual ~EventThread (void){ + ~EventThread (void){ terminate(); } - virtual void run () = 0; + virtual void run () ; private: EventThread(const EventThread& rh); // copy constructor @@ -57,25 +51,5 @@ class EventThread : public ost::Thread { VoIPLink* _linkthread; }; -class IAXEventThread : public EventThread { - - public: - IAXEventThread( VoIPLink* voiplink ) - : EventThread( voiplink ){ - } - - virtual void run(); -}; - -class SIPEventThread : public EventThread { - - public: - SIPEventThread( VoIPLink* voiplink ) - : EventThread( voiplink ){ - } - - virtual void run(); -}; - #endif // __EVENT_THREAD_H__ diff --git a/src/iaxaccount.cpp b/src/iaxaccount.cpp index 364f0ab31b028944112bc177ce85e2b45e6e3b81..22672437cb0e2bbaec42f7f7be1390dc4f4eb5ff 100644 --- a/src/iaxaccount.cpp +++ b/src/iaxaccount.cpp @@ -23,7 +23,7 @@ #include "iaxvoiplink.h" IAXAccount::IAXAccount(const AccountID& accountID) -: Account(accountID) +: Account(accountID, "iax2") { _link = new IAXVoIPLink(accountID); } @@ -35,8 +35,7 @@ IAXAccount::~IAXAccount() _link = NULL; } - int -IAXAccount::registerVoIPLink() +int IAXAccount::registerVoIPLink() { IAXVoIPLink *thislink; diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp index 464bf2b9cc7f477f60697b652845062ac819e0fc..035cb3675b7f0629ee857264541f0eac774a9203 100644 --- a/src/iaxvoiplink.cpp +++ b/src/iaxvoiplink.cpp @@ -45,7 +45,7 @@ IAXVoIPLink::IAXVoIPLink(const AccountID& accountID) : VoIPLink(accountID) { - _evThread = new IAXEventThread(this); + _evThread = new EventThread(this); _regSession = NULL; _nextRefreshStamp = 0; @@ -207,7 +207,7 @@ IAXVoIPLink::getEvent() // Refresh registration. if (_nextRefreshStamp && _nextRefreshStamp - 2 < time(NULL)) { - sendRegister(); + sendRegister(-1); } // thread wait 3 millisecond @@ -308,7 +308,7 @@ IAXVoIPLink::getIAXCall(const CallID& id) int -IAXVoIPLink::sendRegister() +IAXVoIPLink::sendRegister(AccountID id UNUSED) { bool result = false; if (_host.empty()) { diff --git a/src/iaxvoiplink.h b/src/iaxvoiplink.h index fe8978c1b390724ea8a8d2e172a4e15ee359fc25..bae6df69f55ca1e3dfd4fca245f14485c5a7ae3e 100644 --- a/src/iaxvoiplink.h +++ b/src/iaxvoiplink.h @@ -76,7 +76,7 @@ class IAXVoIPLink : public VoIPLink * Send out registration * @return bool The new registration state (are we registered ?) */ - int sendRegister (void); + int sendRegister (AccountID id); /** * Destroy registration session diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index e7af691255f2101c6a2f637c2384271e2a088523..619d494894b9ee5376732405a537ceb4ec938f1d 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -680,7 +680,7 @@ ManagerImpl::startVoiceMessageNotification(const AccountID& accountId, int nb_ms if (_dbus) _dbus->getCallManager()->voiceMailNotify(accountId, nb_msg) ; } -void ManagerImpl::connectionStatusNotification( void ) +void ManagerImpl::connectionStatusNotification( ) { if (_dbus) _dbus->getConfigurationManager()->accountsChanged(); @@ -1701,88 +1701,6 @@ int ManagerImpl::getSipPort( void ) } -/** - * configuration function requests - * Main Thread - */ - bool -ManagerImpl::getZeroconf(const std::string& sequenceId) -{ - bool returnValue = false; -#ifdef USE_ZEROCONF - int useZeroconf = getConfigInt(PREFERENCES, CONFIG_ZEROCONF); - if (useZeroconf && _dbus != NULL) { - TokenList arg; - TokenList argTXT; - std::string newService = "new service"; - std::string newTXT = "new txt record"; - if (!_DNSService->isStart()) { _DNSService->startScanServices(); } - DNSServiceMap services = _DNSService->getServices(); - DNSServiceMap::iterator iter = services.begin(); - arg.push_back(newService); - while(iter!=services.end()) { - arg.push_front(iter->first); - //_gui->sendMessage("100",sequenceId,arg); - arg.pop_front(); // remove the first, the name - - TXTRecordMap record = iter->second.getTXTRecords(); - TXTRecordMap::iterator iterTXT = record.begin(); - while(iterTXT!=record.end()) { - argTXT.clear(); - argTXT.push_back(iter->first); - argTXT.push_back(iterTXT->first); - argTXT.push_back(iterTXT->second); - argTXT.push_back(newTXT); - // _gui->sendMessage("101",sequenceId,argTXT); - iterTXT++; - } - iter++; - } - returnValue = true; - } -#else - (void)sequenceId; -#endif - return returnValue; -} - -/** - * Main Thread - */ - bool -ManagerImpl::attachZeroconfEvents(const std::string& sequenceId, Pattern::Observer& observer) -{ - bool returnValue = false; - // don't need the _gui like getZeroconf function - // because Observer is here -#ifdef USE_ZEROCONF - int useZeroconf = getConfigInt(PREFERENCES, CONFIG_ZEROCONF); - if (useZeroconf) { - if (!_DNSService->isStart()) { _DNSService->startScanServices(); } - _DNSService->attach(observer); - returnValue = true; - } -#else - (void)sequenceId; - (void)observer; -#endif - return returnValue; -} - bool -ManagerImpl::detachZeroconfEvents(Pattern::Observer& observer) -{ - bool returnValue = false; -#ifdef USE_ZEROCONF - if (_DNSService) { - _DNSService->detach(observer); - returnValue = true; - } -#else - (void)observer; -#endif - return returnValue; -} - // TODO: rewrite this /** * Main Thread @@ -2227,8 +2145,25 @@ ManagerImpl::getAccountIdFromNameAndServer(const std::string& userName, const st return AccountNULL; } - VoIPLink* -ManagerImpl::getAccountLink(const AccountID& accountID) +AccountMap ManagerImpl::getSipAccountMap( void ) +{ + + AccountMap::iterator iter; + AccountMap sipaccounts; + AccountID id; + Account *account; + + for(iter = _accountMap.begin(); iter != _accountMap.end(); ++iter) { + if( iter->second->getType() == "sip" ){ + //id = iter->first; + //account = iter->second; + //sipaccounts.insert( std::pair<id, account> ); + } + } + return sipaccounts; +} + +VoIPLink* ManagerImpl::getAccountLink(const AccountID& accountID) { Account* acc = getAccount(accountID); if ( acc ) { diff --git a/src/managerimpl.h b/src/managerimpl.h index 68a40075d5b0eda4dd3451cb47796e44757040f8..a556b9175cdda6677dc9624757a27d0cd8e27589 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -271,9 +271,6 @@ class ManagerImpl { */ void sendRegister( const ::std::string& accountId , const int32_t& 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); /** @@ -798,6 +795,11 @@ class ManagerImpl { void registerCurSIPAccounts(); + /** + * Returns a map with only the existing SIP accounts + */ + AccountMap getSipAccountMap( void ); + private: /** diff --git a/src/sipaccount.cpp b/src/sipaccount.cpp index 27f1acacee36034d29c2af543c77d0da7cced26a..5270e39df7a3aea627dd51bfac68e1b43e55f225 100644 --- a/src/sipaccount.cpp +++ b/src/sipaccount.cpp @@ -25,9 +25,7 @@ #include "user_cfg.h" SIPAccount::SIPAccount(const AccountID& accountID) - : Account(accountID) - , _userName("") - , _server("") + : Account(accountID, "sip") , _cred(NULL) , _contact("") { @@ -46,56 +44,51 @@ SIPAccount::~SIPAccount() int SIPAccount::registerVoIPLink() { - int status, useStun; SIPVoIPLink *thislink; /* Retrieve the account information */ - _link->setHostname(Manager::instance().getConfigString(_accountID,HOSTNAME)); - useStun = Manager::instance().getConfigInt(_accountID,SIP_USE_STUN); + /* Stuff needed for SIP registration */ + setHostname(Manager::instance().getConfigString(_accountID,HOSTNAME)); + setUsername(Manager::instance().getConfigString(_accountID, USERNAME)); + setPassword(Manager::instance().getConfigString(_accountID, PASSWORD)); + /* Retrieve STUN stuff */ + /* STUN configuration is attached to a voiplink because it is applied to every accounts (PJSIP limitation)*/ thislink = dynamic_cast<SIPVoIPLink*> (_link); - thislink->setStunServer(Manager::instance().getConfigString(_accountID,SIP_STUN_SERVER)); - thislink->setUseStun( useStun!=0 ? true : false); - + if (thislink) { + useStun = Manager::instance().getConfigInt(_accountID,SIP_USE_STUN); + thislink->setStunServer(Manager::instance().getConfigString(_accountID,SIP_STUN_SERVER)); + thislink->setUseStun( useStun!=0 ? true : false); + } + /* Link initialization */ _link->init(); - - // Stuff needed for SIP registration. - thislink->setUsername(Manager::instance().getConfigString(_accountID, USERNAME)); - thislink->setPassword(Manager::instance().getConfigString(_accountID, PASSWORD)); - thislink->setHostname(Manager::instance().getConfigString(_accountID, HOSTNAME)); - // Start registration - status = _link->sendRegister(); + /* Start registration */ + status = _link->sendRegister( _accountID ); ASSERT( status , SUCCESS ); return SUCCESS; } -int -SIPAccount::unregisterVoIPLink() +int SIPAccount::unregisterVoIPLink() { _debug("SIPAccount: unregister account %s\n" , getAccountID().c_str()); - _link->sendUnregister(); - - return SUCCESS; + return _link->sendUnregister(); } -void -SIPAccount::loadConfig() +void SIPAccount::loadConfig() { // Account generic Account::loadConfig(); } -bool -SIPAccount::fullMatch(const std::string& userName, const std::string& server) +bool SIPAccount::fullMatch(const std::string& username, const std::string& hostname) { - return (userName == _userName && server == _server); + return (username == getUsername() && hostname == getHostname()); } -bool -SIPAccount::userMatch(const std::string& userName) +bool SIPAccount::userMatch(const std::string& username) { - return (userName == _userName); + return (username == getUsername()); } diff --git a/src/sipaccount.h b/src/sipaccount.h index 549d1a6d0d857326720e81b9863df9a4ca045083..dfbc55774f4a9fcb19327ebdbb303f0ca0b97bc2 100644 --- a/src/sipaccount.h +++ b/src/sipaccount.h @@ -33,69 +33,75 @@ class SIPVoIPLink; /** * @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); - - /* Copy Constructor */ - SIPAccount(const SIPAccount& rh); + public: + /** + * Constructor + * @param accountID The account identifier + */ + SIPAccount(const AccountID& accountID); - /* Assignment Operator */ - SIPAccount& operator=( const SIPAccount& rh); - - /** - * Virtual destructor - */ - virtual ~SIPAccount(); + /* Copy Constructor */ + SIPAccount(const SIPAccount& rh); - /** - * Actually unuseful, since config loading is done in init() - */ - void loadConfig(); + /* Assignment Operator */ + SIPAccount& operator=( const SIPAccount& rh); - /** - * Initialize the SIP voip link with the account parameters and send registration - */ - int registerVoIPLink(); + /** + * Virtual destructor + */ + virtual ~SIPAccount(); - /** - * Send unregistration and clean all related stuff ( calls , thread ) - */ - int unregisterVoIPLink(); + /** + * Actually unuseful, since config loading is done in init() + */ + void loadConfig(); + /** + * Initialize the SIP voip link with the account parameters and send registration + */ + int registerVoIPLink(); - void setUserName(const std::string &name) {_userName = name;} + /** + * Send unregistration and clean all related stuff ( calls , thread ) + */ + int unregisterVoIPLink(); - std::string getUserName() {return _userName;} + inline void setCredInfo(pjsip_cred_info *cred) {_cred = cred;} + inline pjsip_cred_info *getCredInfo() {return _cred;} - void setServer(const std::string &server) {_server = server;} + inline void setContact(const std::string &contact) {_contact = contact;} + inline std::string getContact() {return _contact;} - std::string getServer() {return _server;} + bool fullMatch(const std::string& username, const std::string& hostname); + bool userMatch(const std::string& username); - void setCredInfo(pjsip_cred_info *cred) {_cred = cred;} + inline std::string getHostname( void ) { return _hostname; } + inline void setHostname( std::string hostname) { _hostname = hostname; } - pjsip_cred_info *getCredInfo() {return _cred;} + inline std::string getPassword( void ) { return _password; } + inline void setPassword( std::string password ) { _password = password; } - void setContact(const std::string contact) {_contact = contact;} + inline std::string getAlias( void ) { return _alias; } + inline void setAlias( std::string alias ) { _alias = alias; } - std::string getContact() {return _contact;} + inline std::string getType( void ) { return _type; } + inline void setType( std::string type ) { _type = type; } - bool fullMatch(const std::string& userName, const std::string& server); - bool userMatch(const std::string& userName); + private: + /** + * Credential information + */ + pjsip_cred_info *_cred; -private: - std::string _userName; - std::string _server; - pjsip_cred_info *_cred; - std::string _contact; + /* + * SIP address + */ + std::string _contact; }; #endif diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index d05ebd56f83ba2db81708bbee7b8d62d840ee778..42e9887e837d97ce43845f29bef36d9fa0f61958 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -2,8 +2,7 @@ * Copyright (C) 2004-2009 Savoir-Faire Linux inc. * * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * Author : Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * Author: Yun Liu <yun.liu@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 @@ -75,26 +74,23 @@ void xfer_svr_cb(pjsip_evsub *sub, pjsip_event *event); void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata); /*******************************/ - - SIPVoIPLink::SIPVoIPLink(const AccountID& accountID) : VoIPLink(accountID) - , _initDone(false) , _nbTryListenAddr(2) // number of times to try to start SIP listener - , _stunServer("") - , _localExternAddress("") + , _stunServer("") + , _localExternAddress("") , _localExternPort(0) , _audiortp(new AudioRtp()) , _regc() , _bRegister(false) - ,_regPort(DEFAULT_SIP_PORT) + ,_regPort(DEFAULT_SIP_PORT) { // to get random number for RANDOM_PORT srand (time(NULL)); _useStun = false; _localIPAddress = "127.0.0.1"; - _evThread = new SIPEventThread(this); + _evThread = new EventThread(this); } SIPVoIPLink::~SIPVoIPLink() @@ -113,13 +109,14 @@ SIPVoIPLink* SIPVoIPLink::instance( const AccountID& id){ bool SIPVoIPLink::init() { + if(_initDone) + return false; /* Initialize the pjsip library */ - if( !isInitDone() ){ - _regc = NULL; - pjsip_init(); - } + _regc = NULL; + if(!pjsip_init()) + return false; - setInitState(true); + _initDone = true; return true; } @@ -127,7 +124,8 @@ bool SIPVoIPLink::init() SIPVoIPLink::terminate() { /* Clean shutdown of pjsip library */ - pjsip_shutdown(); + if( _initDone ) + pjsip_shutdown(); _initDone = false; } @@ -167,10 +165,8 @@ SIPVoIPLink::getEvent() _mutexSIP.leaveMutex(); } -int SIPVoIPLink::sendRegister() +int SIPVoIPLink::sendRegister( AccountID id ) { - - AccountID id; pj_status_t status; int expire_value; char contactTmp[256]; @@ -179,11 +175,10 @@ int SIPVoIPLink::sendRegister() std::string tmp, hostname, username, password; SIPAccount *account; - /* Get the current account ID */ - id = getAccountID(); - hostname = getHostname(); - username = getUsername(); - password = getPassword(); + account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(id)); + hostname = account->getHostname(); + username = account->getUsername(); + password = account->getPassword(); _mutexSIP.enterMutex(); @@ -209,6 +204,7 @@ int SIPVoIPLink::sendRegister() return false; } + /* Create the registration according to the account ID */ status = pjsip_regc_create(_endpt, (void*)new AccountID(id), ®c_cb, &_regc); if (status != PJ_SUCCESS) { _debug("UserAgent: Unable to create regc.\n"); @@ -224,6 +220,7 @@ int SIPVoIPLink::sendRegister() sprintf(contactTmp, "<sip:%s@%s:%d>", username.data(), _localExternAddress.data(), _localExternPort); pj_strdup2(_pool, &contact, contactTmp); + account->setContact(contactTmp); status = pjsip_regc_init(_regc, &svr, &aor, &aor, 1, &contact, 600); //timeout); if (status != PJ_SUCCESS) { @@ -232,7 +229,6 @@ int SIPVoIPLink::sendRegister() return false; } - account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(id)); pjsip_cred_info *cred = account->getCredInfo(); if(!cred) @@ -261,46 +257,18 @@ int SIPVoIPLink::sendRegister() _mutexSIP.leaveMutex(); return false; } - - account->setUserName(username); - account->setServer(hostname); - account->setContact(contactTmp); - + _mutexSIP.leaveMutex(); return true; } - - std::string -SIPVoIPLink::SIPFromHeader(const std::string& userpart, const std::string& hostpart) -{ - return ("\"" + getFullName() + "\"" + " <sip:" + userpart + "@" + hostpart + ">"); -} - - bool -SIPVoIPLink::sendSIPAuthentification() -{ - if (getUsername().empty()) { - /** @todo Ajouter ici un call à setRegistrationState(Error, "Fill balh") ? */ - return false; - } - if (getPassword().empty()) { - /** @todo Même chose ici ? */ - return false; - } - - return true; -} - int SIPVoIPLink::sendUnregister() { pj_status_t status = 0; pjsip_tx_data *tdata = NULL; - _debug("SEND UNREGISTER for account %s\n" , getAccountID().c_str()); - if(!isRegister()){ setRegistrationState(VoIPLink::Unregistered); return true; @@ -331,10 +299,14 @@ SIPVoIPLink::sendUnregister() Call* SIPVoIPLink::newOutgoingCall(const CallID& id, const std::string& toUrl) { + Account* account; + SIPCall* call = new SIPCall(id, Call::Outgoing); + if (call) { + account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(Manager::instance().getAccountFromCall(id))); //call->setPeerNumber(toUrl); - call->setPeerNumber(getSipTo(toUrl)); + call->setPeerNumber(getSipTo(toUrl, account->getHostname())); _debug("Try to make a call to: %s with call ID: %s\n", toUrl.data(), id.data()); // we have to add the codec before using it in SIPOutgoingInvite... call->setCodecMap(Manager::instance().getCodecDescriptorMap()); @@ -545,8 +517,13 @@ SIPVoIPLink::transfer(const CallID& id, const std::string& to) struct pjsip_evsub_user xfer_cb; pj_status_t status; pj_str_t dest; + AccountID account_id; + Account* account; + call = getSIPCall(id); + account_id = Manager::instance().getAccountFromCall(id); + account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(account_id)); if (call==0) { _debug("! SIP Failure: Call doesn't exist\n"); @@ -555,7 +532,7 @@ SIPVoIPLink::transfer(const CallID& id, const std::string& to) tmp_to = SIPToHeader(to); if (tmp_to.find("@") == std::string::npos) { - tmp_to = tmp_to + "@" + getHostname(); + tmp_to = tmp_to + "@" + account->getHostname(); } _debug("In transfer, tmp_to is %s\n", tmp_to.data()); @@ -723,15 +700,15 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject UNUSED) if (!call) return false; - strTo = getSipTo(call->getPeerNumber()); - _debug(" To: %s\n", strTo.data()); - - id = getAccountID(); + id = Manager::instance().getAccountFromCall(call->getCallId()); // Get the basic information about the callee account account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(id)); + + strTo = getSipTo(call->getPeerNumber(), account->getHostname()); + _debug(" To: %s\n", strTo.data()); // Generate the from URI - strFrom = "sip:" + account->getUserName() + "@" + account->getServer(); + strFrom = "sip:" + account->getUsername() + "@" + account->getHostname(); // pjsip need the from and to information in pj_str_t format pj_strdup2(_pool, &from, strFrom.data()); @@ -777,42 +754,27 @@ SIPVoIPLink::SIPStartCall(SIPCall* call, const std::string& subject UNUSED) return true; } -std::string -SIPVoIPLink::getSipFrom() { - - // Form the From header field basis on configuration panel - std::string hostname; - - hostname = getHostname(); - - if ( hostname.empty() ) { - hostname = _localIPAddress; - } - return SIPFromHeader(getUsername(), hostname); -} - -std::string SIPVoIPLink::getSipTo(const std::string& to_url) { +std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostname) { // Form the From header field basis on configuration panel //bool isRegistered = (_eXosipRegID == EXOSIP_ERROR_STD) ? false : true; // add a @host if we are registered and there is no one inside the url if (to_url.find("@") == std::string::npos) {// && isRegistered) { - std::string host = getHostname(); - if(!host.empty()) { - return SIPToHeader(to_url + "@" + host); + if(!hostname.empty()) { + return SIPToHeader(to_url + "@" + hostname); } } return SIPToHeader(to_url); } - std::string SIPVoIPLink::SIPToHeader(const std::string& to) - { - if (to.find("sip:") == std::string::npos) { - return ("sip:" + to ); - } else { - return to; - } +std::string SIPVoIPLink::SIPToHeader(const std::string& to) +{ + if (to.find("sip:") == std::string::npos) { + return ("sip:" + to ); + } else { + return to; } +} bool SIPVoIPLink::SIPCheckUrl(const std::string& url UNUSED) diff --git a/src/sipvoiplink.h b/src/sipvoiplink.h index c00479a5b2983ebd8699f94061d87a101e527109..cf67cd7ca47c3692bf3f557646a9ea5e3efd3e8d 100644 --- a/src/sipvoiplink.h +++ b/src/sipvoiplink.h @@ -48,303 +48,272 @@ class AudioRtp; class SIPVoIPLink : public VoIPLink { - public: - - /** - * Constructor - * @param accountID The account identifier - */ - SIPVoIPLink(const AccountID& accountID); - - static SIPVoIPLink* instance( const AccountID& id ); - - /** - * Destructor - */ - ~SIPVoIPLink(); - - /* Copy Constructor */ - SIPVoIPLink(const SIPVoIPLink& rh); - - /* Assignment Operator */ - SIPVoIPLink& operator=( const SIPVoIPLink& rh); - - /** - * Try to initiate the pjsip engine/thread and set config - * @return bool True if OK - */ - bool init(void); - - void terminate( 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 - */ - int sendRegister(void); - - /** - * Build and send SIP unregistration request - * @return bool True on success - * false otherwise - */ - int 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); - - /** Handle the incoming refer msg, not finished yet */ - bool transferStep2(); - - /** - * 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); - - /** - * If set to true, we check for a firewall - * @param use true if we use STUN - */ - void setUseStun(bool use); - - bool useStun( void ); - - /** - * The name of the STUN server - * @param server Server FQDN/IP - */ - void setStunServer(const std::string& server) { _stunServer = server; } - - bool isRegister() {return _bRegister;} - - void setRegister(bool result) {_bRegister = result;} - - public: - - /** - * Terminate every call not hangup | brutal | Protected by mutex - */ - void terminateSIPCall(); - - /** - * 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 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); + public: /** - * Tell the user that the call was answered - * @param - */ - void SIPCallAnswered(SIPCall *call, pjsip_rx_data *rdata); - - /** - * Handling 5XX/6XX error - * @param - */ - void SIPCallServerFailure(SIPCall *call); - - /** - * Peer close the connection - * @param - */ - void SIPCallClosed(SIPCall *call); - - /** - * The call pointer was released - * If the call was not cleared before, report an error - * @param - */ - void SIPCallReleased(SIPCall *call); - - bool isInitDone() { return _initDone; } - - void setInitState( bool state ){ _initDone = state; } - - /** - * SIPCall accessor - * @param id The call identifier - * @return SIPCall* A pointer on SIPCall object - */ - SIPCall* getSIPCall(const CallID& id); + * Constructor + * @param accountID The account identifier + */ + SIPVoIPLink(const AccountID& accountID); + + static SIPVoIPLink* instance( const AccountID& id ); + + /** + * Destructor + */ + ~SIPVoIPLink(); + + /* Copy Constructor */ + SIPVoIPLink(const SIPVoIPLink& rh); + + /* Assignment Operator */ + SIPVoIPLink& operator=( const SIPVoIPLink& rh); + + /** + * Try to initiate the pjsip engine/thread and set config + * @return bool True if OK + */ + bool init(void); + + void terminate( 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 + */ + int sendRegister(AccountID id); + + /** + * Build and send SIP unregistration request + * @return bool True on success + * false otherwise + */ + int 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); + + /** Handle the incoming refer msg, not finished yet */ + bool transferStep2(); + + /** + * 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); + + /** + * If set to true, we check for a firewall + * @param use true if we use STUN + */ + void setUseStun(bool use); + + bool useStun( void ); + + /** + * The name of the STUN server + * @param server Server FQDN/IP + */ + void setStunServer(const std::string& server) { _stunServer = server; } + + bool isRegister() {return _bRegister;} + + void setRegister(bool result) {_bRegister = result;} + + /** + * Terminate every call not hangup | brutal | Protected by mutex + */ + void terminateSIPCall(); + + /** + * 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 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, std::string hostname); + + /** + * Tell the user that the call was answered + * @param + */ + void SIPCallAnswered(SIPCall *call, pjsip_rx_data *rdata); + + /** + * Handling 5XX/6XX error + * @param + */ + void SIPCallServerFailure(SIPCall *call); + + /** + * Peer close the connection + * @param + */ + void SIPCallClosed(SIPCall *call); + + /** + * The call pointer was released + * If the call was not cleared before, report an error + * @param + */ + void SIPCallReleased(SIPCall *call); + + /** + * SIPCall accessor + * @param id The call identifier + * @return SIPCall* A pointer on SIPCall object + */ + SIPCall* getSIPCall(const CallID& id); /** when we init the listener, how many times we try to bind a port? */ - int _nbTryListenAddr; - - /** Starting sound */ - AudioRtp* _audiortp; - - pj_str_t string2PJStr(const std::string &value); - -private: - static SIPVoIPLink* _instance; - - int getModId(); - /** - * Initialize the PJSIP library - * Must be called before any other calls to the SIP layer - * - * @return bool True on success - */ - bool pjsip_init(); - - /** - * Delete link-related stuuf like calls - */ - bool pjsip_shutdown(void); - - pj_status_t stunServerResolve(); - - /** Create SIP UDP Listener */ - int createUDPServer(); - - bool loadSIPLocalIP(); - - std::string getLocalIP() {return _localExternAddress;} - - pjsip_regc *_regc; - - /** For registration use only */ - int _regPort; - - /** Tell if the initialisation has been done */ - bool _initDone; - - /* Flag to check if the STUN server is valid or not */ - bool validStunServer; - - /** The current STUN server address */ - std::string _stunServer; - - /** Local Extern Address is the IP address seen by peers for SIP listener */ - std::string _localExternAddress; - std::string _localIPAddress; - - /** Local Extern Port is the port seen by peers for SIP listener */ - unsigned int _localExternPort; - unsigned int _localPort; - - /** Threading object */ - EventThread* _evThread; - ost::Mutex _mutexSIP; - - bool _bRegister; + int _nbTryListenAddr; + + /** Starting sound */ + AudioRtp* _audiortp; + + pj_str_t string2PJStr(const std::string &value); + + private: + static SIPVoIPLink* _instance; + + int getModId(); + /** + * Initialize the PJSIP library + * Must be called before any other calls to the SIP layer + * + * @return bool True on success + */ + bool pjsip_init(); + + /** + * Delete link-related stuuf like calls + */ + bool pjsip_shutdown(void); + + pj_status_t stunServerResolve(); + + /** Create SIP UDP Listener */ + int createUDPServer(); + + bool loadSIPLocalIP(); + + std::string getLocalIP() {return _localExternAddress;} + + pjsip_regc *_regc; + + /** For registration use only */ + int _regPort; + + /* Flag to check if the STUN server is valid or not */ + bool validStunServer; + + /** The current STUN server address */ + 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; + + /** Threading object */ + EventThread* _evThread; + ost::Mutex _mutexSIP; + + bool _bRegister; }; #endif diff --git a/src/voiplink.cpp b/src/voiplink.cpp index fe62b20467a1047fa2a1965618de1bff4abeea79..46b69582329a1302a77a1c705d3713df98ba0ec8 100644 --- a/src/voiplink.cpp +++ b/src/voiplink.cpp @@ -26,7 +26,6 @@ VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0), _initDone(false) { - setRegistrationState(VoIPLink::Unregistered); } VoIPLink::~VoIPLink (void) @@ -64,8 +63,7 @@ Call* VoIPLink::getCall(const CallID& id) return 0; } -bool -VoIPLink::clearCallMap() +bool VoIPLink::clearCallMap() { ost::MutexLock m(_callMapMutex); CallMap::iterator iter = _callMap.begin(); @@ -78,9 +76,10 @@ VoIPLink::clearCallMap() return true; } -void VoIPLink::setRegistrationState(const RegistrationState state) +void VoIPLink::setRegistrationState(AccountID id, const RegistrationState state) { - _registrationState = state; - // Notify the client - Manager::instance().connectionStatusNotification( ); + Account *account; + + account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(id)); + account->setRegistrationState( state ); } diff --git a/src/voiplink.h b/src/voiplink.h index e095c1922ccc24af99754eddd5ed79b1d2ebc83a..2261211edc5ad86a1e0ca65f5251478a63dd92cf 100644 --- a/src/voiplink.h +++ b/src/voiplink.h @@ -38,8 +38,8 @@ typedef std::map<CallID, Call*> CallMap; * @brief Listener and manager interface for each VoIP protocol */ class VoIPLink { - public: - + + public: /** * Constructor * @param accountID The account identifier @@ -51,10 +51,7 @@ class VoIPLink { */ virtual ~VoIPLink (void); - /** Contains all the state an Voip can be in */ - enum RegistrationState {Unregistered, Trying, Registered, Error, ErrorAuth , ErrorNetwork , ErrorHost, ErrorExistStun, ErrorConfStun}; - typedef enum RegistrationState RegistrationState; - + /** * Virtual method * Event listener. Each event send by the call manager is received and handled from here @@ -63,28 +60,28 @@ class VoIPLink { /** * Virtual method - * Try to initiate the pjsip engine/thread and set config + * Try to initiate the communication layer and set config * @return bool True if OK */ virtual bool init (void) = 0; /** * Virtual method - * Delete link-related stuuf like calls + * Delete link-related stuff like calls */ virtual void terminate (void) = 0; /** * Virtual method - * Build and send SIP registration request + * Build and send account registration request * @return bool True on success * false otherwise */ - virtual int sendRegister (void) = 0; + virtual int sendRegister ( AccountID id ) = 0; /** * Virtual method - * Build and send SIP unregistration request + * Build and send account unregistration request * @return bool True on success * false otherwise */ @@ -93,10 +90,11 @@ class VoIPLink { /** * Place a new call * @param id The call identifier - * @param toUrl The Sip address of the recipient of the call + * @param toUrl The 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 @@ -155,53 +153,54 @@ class VoIPLink { */ virtual bool carryingDTMFdigits(const CallID& id, char code) = 0; - /* Accessors */ - std::string& getFullName (void) { return _fullname; } - void setFullName (const std::string& fullname) { _fullname = fullname; } - - std::string& getHostname (void) { return _hostname; } - void setHostname (const std::string& hostname) { _hostname = hostname; } - - std::string& getUsername (void) { return _username; } - void setUsername (const std::string& username) { _username = username; } + /** 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); - std::string& getPassword (void) { return _password; } - void setPassword (const std::string& password) { _password = password; } + /** 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(); + /** * @return AccountID parent Account's ID */ - AccountID& getAccountID(void) { return _accountID; } + inline AccountID& getAccountID(void) { return _accountID; } /** * @param accountID The account identifier */ - void setAccountID( const AccountID& accountID) { _accountID = accountID; } + inline void setAccountID( const AccountID& accountID) { _accountID = accountID; } - /** Get the call pointer from the call map (protected by mutex) + /** + * 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 connection status + * Get an account connection status * @return Connection status */ - RegistrationState getRegistrationState() { return _registrationState; } + RegistrationState getRegistrationState( void ); /** * Set new registration state * @param state The registration state */ - void setRegistrationState(const RegistrationState state); + void setRegistrationState(AccountID id, const RegistrationState state); private: - std::string _hostname; - std::string _username; - std::string _password; - std::string _fullname; - /** * ID of parent's Account */ @@ -212,26 +211,6 @@ class VoIPLink { */ RegistrationState _registrationState; -public: - /** 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(); - - protected: /** Contains all the calls for this Link, protected by mutex */ CallMap _callMap;