Commit ba1e6d86 authored by Alexandre Bourget's avatar Alexandre Bourget

Major Account registration, state reporting, update.

* Renamed setRegister/setUnregister to sendRegister/sendUnregister, reflecting
  more precisely what the function does.
* Renamed (un)registerAccount to (un)registerVoIPLink in account/iaxaccount/sipaccount
* Renamed (un)registerVoIPLink to (un)registerAccount in managerimpl.cpp|h
* Prepared the way for dynamic registration reporting (to the GUI). Now has
  more precise way to describe reg. state: Unregistered, Trying, Error, Registered
* Delete `_link` on SIPAccount/IAXAccount destruction
* All sync of the regist. state with the Manager, is now done in
  VoIPLink::setRegistrationState()
* Document all the way
parent b389d021
......@@ -83,16 +83,18 @@ class Account{
inline VoIPLink* getVoIPLink() { return _link; }
/**
* Register the account
* Register the underlying VoIPLink
*
* @return false is an error occurs
*/
virtual bool registerAccount() = 0;
virtual bool registerVoIPLink() = 0;
/**
* Unregister the account
* Unregister the underlying VoIPLink
*
* @return false is an error occurs
*/
virtual bool unregisterAccount() = 0;
virtual bool unregisterVoIPLink() = 0;
/**
* Init the voiplink to run (event listener)
......
......@@ -31,10 +31,11 @@ IAXAccount::IAXAccount(const AccountID& accountID)
IAXAccount::~IAXAccount()
{
delete _link;
}
bool
IAXAccount::registerAccount()
IAXAccount::registerVoIPLink()
{
if (_link && !_registered) {
init();
......@@ -46,16 +47,16 @@ IAXAccount::registerAccount()
tmplink->setUser(Manager::instance().getConfigString(_accountID, IAX_USER));
tmplink->setPass(Manager::instance().getConfigString(_accountID, IAX_PASS));
}
_registered = _link->setRegister();
_registered = _link->sendRegister();
}
return _registered;
}
bool
IAXAccount::unregisterAccount()
IAXAccount::unregisterVoIPLink()
{
if (_link && _registered) {
_registered = _link->setUnregister();
_registered = _link->sendUnregister();
}
return !_registered;
}
......
......@@ -38,8 +38,8 @@ public:
void initConfig(Conf::ConfigTree& config);
/** Actually unuseful, since config loading is done in init() */
void loadConfig();
bool registerAccount();
bool unregisterAccount();
bool registerVoIPLink();
bool unregisterVoIPLink();
bool init();
bool terminate();
......
......@@ -206,7 +206,7 @@ IAXVoIPLink::getEvent()
// Refresh registration.
if (_nextRefreshStamp && _nextRefreshStamp - 2 < time(NULL)) {
setRegister();
sendRegister();
}
// thread wait 5 millisecond
......@@ -354,14 +354,6 @@ IAXVoIPLink::sendAudioFromMic(void)
}
/*
void IAXVoIPLink::recvAudioForSpkr(void)
{
}
*/
IAXCall*
IAXVoIPLink::getIAXCall(const CallID& id)
{
......@@ -375,7 +367,7 @@ IAXVoIPLink::getIAXCall(const CallID& id)
bool
IAXVoIPLink::setRegister()
IAXVoIPLink::sendRegister()
{
bool result = false;
......@@ -427,10 +419,10 @@ IAXVoIPLink::setRegister()
bool
IAXVoIPLink::setUnregister()
IAXVoIPLink::sendUnregister()
{
if (_regSession) {
/** @todo Should send a REGREL in setUnregister()... */
/** @todo Should send a REGREL in sendUnregister()... */
_mutexIAX.enterMutex();
//iax_send_regrel(); doesn't exist yet :)
......@@ -827,7 +819,9 @@ IAXVoIPLink::iaxHandleRegReply(iax_event* event)
_mutexIAX.leaveMutex();
_regSession = NULL;
Manager::instance().registrationFailed(getAccountID());
setRegistrationState(Error, "Registration failed");
//Manager::instance().registrationFailed(getAccountID());
}
else if (event->etype == IAX_EVENT_REGACK) {
/* Authentication succeeded */
......@@ -840,7 +834,8 @@ IAXVoIPLink::iaxHandleRegReply(iax_event* event)
// Defaults to 60, as per draft-guy-iax-03.
_nextRefreshStamp = time(NULL) + (event->ies.refresh ? event->ies.refresh : 60);
Manager::instance().registrationSucceed(getAccountID());
setRegistrationState(Registered);
//Manager::instance().registrationSucceed(getAccountID());
}
}
......
......@@ -59,7 +59,7 @@ public:
*
* @return The new registration state (are we registered ?)
*/
bool setRegister (void);
bool sendRegister (void);
/**
* Destroy registration session
......@@ -69,7 +69,7 @@ public:
*
* @return bool If we're registered upstream
*/
bool setUnregister (void);
bool sendUnregister (void);
Call* newOutgoingCall(const CallID& id, const std::string& toUrl);
bool answer(const CallID& id);
......
......@@ -135,7 +135,7 @@ ManagerImpl::init()
_dtmfKey = new DTMF(sampleRate);
}
// initRegisterVoIP was here, but we doing it after the gui loaded...
// initRegisterAccounts was here, but we doing it after the gui loaded...
// the stun detection is long, so it's a better idea to do it after getEvents
initZeroconf();
}
......@@ -263,6 +263,8 @@ ManagerImpl::hangupCall(const CallID& id)
if (_dbus) _dbus->getCallManager()->callStateChanged(id, "HUNGUP");
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
/** @todo We should tell the GUI that the call doesn't exist, so
* it clears up. This can happen. */
_debug("! Manager Hangup Call: Call doesn't exists\n");
return false;
}
......@@ -306,6 +308,8 @@ ManagerImpl::onHoldCall(const CallID& id)
return false;
}
_debug("Setting ONHOLD, Account %s, callid %s\n", accountid.c_str(), id.c_str());
bool returnValue = getAccountLink(accountid)->onhold(id);
removeWaitingCall(id);
......@@ -332,6 +336,8 @@ ManagerImpl::offHoldCall(const CallID& id)
onHoldCall(getCurrentCallId());
}
_debug("Setting OFFHOLD, Account %s, callid %s\n", accountid.c_str(), id.c_str());
bool returnValue = getAccountLink(accountid)->offhold(id);
if (_dbus) _dbus->getCallManager()->callStateChanged(id, "UNHOLD");
switchCall(id);
......@@ -415,7 +421,7 @@ ManagerImpl::saveConfig (void)
//THREAD=Main
bool
ManagerImpl::initRegisterVoIPLink()
ManagerImpl::initRegisterAccounts()
{
_debugInit("Initiate VoIP Links Registration");
AccountMap::iterator iter = _accountMap.begin();
......@@ -424,7 +430,7 @@ ManagerImpl::initRegisterVoIPLink()
iter->second->loadConfig();
if ( iter->second->shouldInitOnStart() ) {
if ( iter->second->init() && iter->second->shouldRegisterOnStart()) {
iter->second->registerAccount();
iter->second->registerVoIPLink();
}
// init only the first account -- naahh..
//break;
......@@ -437,7 +443,7 @@ ManagerImpl::initRegisterVoIPLink()
//THREAD=Main
bool
ManagerImpl::registerVoIPLink(const AccountID& accountId)
ManagerImpl::registerAccount(const AccountID& accountId)
{
_debug("Register VoIP Link\n");
int returnValue = false;
......@@ -448,24 +454,24 @@ ManagerImpl::registerVoIPLink(const AccountID& accountId)
AccountMap::iterator iter = _accountMap.begin();
while ( iter != _accountMap.end() ) {
if ( iter->second ) {
iter->second->unregisterAccount();
iter->second->unregisterVoIPLink();
iter->second->terminate();
}
iter++;
}
returnValue = account->registerAccount();
returnValue = account->registerVoIPLink();
}
return returnValue;
}
//THREAD=Main
bool
ManagerImpl::unregisterVoIPLink(const AccountID& accountId)
ManagerImpl::unregisterAccount(const AccountID& accountId)
{
_debug("Unregister VoIP Link\n");
int returnValue = false;
if (accountExists( accountId ) ) {
returnValue = getAccount(accountId)->unregisterAccount();
returnValue = getAccount(accountId)->unregisterVoIPLink();
}
return returnValue;
}
......@@ -1243,10 +1249,12 @@ ManagerImpl::detachZeroconfEvents(Pattern::Observer& observer)
/**
* Main Thread
*
* @todo When is this called ? Why this name 'getEvents' ?
*/
bool
ManagerImpl::getEvents() {
initRegisterVoIPLink();
initRegisterAccounts();
return true;
}
......
......@@ -129,21 +129,35 @@ public:
bool saveConfig (void);
/**
* Send registration information (shake hands) for a specific AccountID
*
* @param accountId Account to register
* @return true if setRegister is call without failure, else return false
*/
bool registerVoIPLink(const AccountID& accountId);
* 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 unregisterVoIPLink(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
......@@ -480,11 +494,6 @@ private:
int _firewallPort;
std::string _firewallAddr;
// return false if exosip or the network checking failed
bool initRegisterVoIPLink();
// true if we tried to register Once
bool _hasTriedToRegister;
// tell if we have zeroconf is enabled
int _hasZeroconf;
......
......@@ -31,14 +31,15 @@ SIPAccount::SIPAccount(const AccountID& accountID)
SIPAccount::~SIPAccount()
{
delete _link;
}
bool
SIPAccount::registerAccount()
SIPAccount::registerVoIPLink()
{
if (_link) {
init(); // init if not enable
unregisterAccount();
unregisterVoIPLink();
SIPVoIPLink* tmplink = dynamic_cast<SIPVoIPLink*> (_link);
if (tmplink) {
// Stuff needed for SIP registration.
......@@ -47,16 +48,16 @@ SIPAccount::registerAccount()
tmplink->setAuthName(Manager::instance().getConfigString(_accountID,SIP_AUTH_NAME));
tmplink->setPassword(Manager::instance().getConfigString(_accountID,SIP_PASSWORD));
}
_registered = _link->setRegister();
_registered = _link->sendRegister();
}
return _registered;
}
bool
SIPAccount::unregisterAccount()
SIPAccount::unregisterVoIPLink()
{
if (_link && _registered) {
_registered = _link->setUnregister();
_registered = _link->sendUnregister();
}
return !_registered;
}
......
......@@ -38,8 +38,8 @@ public:
void initConfig(Conf::ConfigTree& config);
/** Actually unuseful, since config loading is done in init() */
void loadConfig();
bool registerAccount();
bool unregisterAccount();
bool registerVoIPLink();
bool unregisterVoIPLink();
bool init();
bool terminate();
......
......@@ -218,15 +218,18 @@ SIPVoIPLink::getEvent()
_debug(" !EXOSIP_REGISTRATION_NEW event is not implemented\n");
break;
case EXOSIP_REGISTRATION_SUCCESS: /** 01 < user is successfully registred. */
Manager::instance().registrationSucceed(getAccountID());
setRegistrationState(Registered);
//Manager::instance().registrationSucceed(getAccountID());
break;
case EXOSIP_REGISTRATION_FAILURE: /** 02 < user is not registred. */
Manager::instance().registrationFailed(getAccountID());
setRegistrationState(Error, "SIP registration failure.");
//Manager::instance().registrationFailed(getAccountID());
break;
case EXOSIP_REGISTRATION_REFRESHED: /** 03 < registration has been refreshed. */
_debug(" !EXOSIP_REGISTRATION_REFRESHED event is not implemented\n");
break;
case EXOSIP_REGISTRATION_TERMINATED: /** 04 < UA is not registred any more. */
setRegistrationState(Unregistered, "Registration terminated by remote host");
_debug(" !EXOSIP_REGISTRATION_TERMINATED event is not implemented\n");
break;
......@@ -354,7 +357,7 @@ SIPVoIPLink::getEvent()
}
bool
SIPVoIPLink::setRegister()
SIPVoIPLink::sendRegister()
{
if (_eXosipRegID != EXOSIP_ERROR_STD) {
Manager::instance().displayError("! SIP Error: Registration already sent. Try to unregister");
......@@ -415,6 +418,8 @@ SIPVoIPLink::setRegister()
}
eXosip_unlock();
setRegistrationState(Trying);
return true;
}
......@@ -432,10 +437,12 @@ SIPVoIPLink::sendSIPAuthentification()
login = _userpart;
}
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;
}
......@@ -447,7 +454,7 @@ SIPVoIPLink::sendSIPAuthentification()
}
bool
SIPVoIPLink::setUnregister()
SIPVoIPLink::sendUnregister()
{
if ( _eXosipRegID == EXOSIP_ERROR_STD) return false;
int eXosipErr = EXOSIP_ERROR_NO;
......@@ -458,7 +465,7 @@ SIPVoIPLink::setUnregister()
eXosip_unlock();
if (eXosipErr != EXOSIP_ERROR_NO) {
_debug("! SIP Failure: Unable to build registration for setUnregister");
_debug("! SIP Failure: Unable to build registration for sendUnregister");
return false;
}
......
......@@ -46,8 +46,8 @@ public:
bool checkNetwork(void);
void getEvent(void);
bool setRegister(void);
bool setUnregister(void);
bool sendRegister(void);
bool sendUnregister(void);
Call* newOutgoingCall(const CallID& id, const std::string& toUrl);
bool answer(const CallID& id);
......
......@@ -23,10 +23,10 @@
#include "user_cfg.h"
#include "voiplink.h"
#include "manager.h"
VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0)
VoIPLink::VoIPLink(const AccountID& accountID) : _accountID(accountID), _localIPAddress("127.0.0.1"), _localPort(0), _registrationError("")
{
}
VoIPLink::~VoIPLink (void)
......@@ -81,3 +81,30 @@ VoIPLink::clearCallMap()
return true;
}
void
VoIPLink::setRegistrationState(const enum RegistrationState state, const std::string& errorMessage)
{
/** @todo Push to the GUI when state changes */
_registrationState = state;
_registrationError = errorMessage;
switch (state) {
case Registered:
Manager::instance().registrationSucceed(getAccountID());
break;
case Trying:
//Manager::instance(). some function to say that
break;
case Error:
Manager::instance().registrationFailed(getAccountID());
break;
case Unregistered:
break;
}
}
void
VoIPLink::setRegistrationState(const enum RegistrationState state)
{
setRegistrationState(state, "");
}
......@@ -37,35 +37,69 @@ typedef std::map<CallID, Call*> CallMap;
*/
class VoIPLink {
public:
VoIPLink(const AccountID& accountID);
virtual ~VoIPLink (void);
VoIPLink(const AccountID& accountID);
virtual ~VoIPLink (void);
// 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 setRegister (void) = 0;
virtual bool setUnregister (void) = 0;
enum RegistrationState {Unregistered, Trying, Registered, Error};
// 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;
virtual bool hangup(const CallID& id) = 0;
virtual bool cancel(const CallID& id) = 0;
virtual bool onhold(const CallID& id) = 0;
virtual bool offhold(const CallID& id) = 0;
virtual bool transfer(const CallID& id, const std::string& to) = 0;
virtual bool refuse(const CallID& id) = 0;
virtual bool carryingDTMFdigits(const CallID& id, char code) = 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;
// 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; }
std::string& getHostName (void) { return _hostname; }
/**
* Return parent Account's ID
*/
AccountID& getAccountID(void) { return _accountID; }
/** Get the call pointer from the call map (protected by mutex)
......@@ -74,12 +108,57 @@ public:
*/
Call* getCall(const CallID& id);
/**
* Get registration state
*/
enum RegistrationState getRegistrationState() { return _registrationState; }
/**
* Get registration error message, if set.
*/
std::string 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 std::string& errorMessage);
/**
* 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 message
*/
std::string _registrationError;
protected:
/** Add a call to the call map (protected by mutex)
* @param call A call pointer with a unique pointer
......@@ -87,7 +166,7 @@ protected:
*/
bool addCall(Call* call);
/** remove a call from the call map (protected by mutex)
/** Remove a call from the call map (protected by mutex)
* @param id A Call ID
* @return true if the call was correctly removed
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment