From 636976e55d9dcb9137a17a39c7596bc4f1c71a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 30 Oct 2014 11:02:20 +0100 Subject: [PATCH] Reworking TunnelManager Some booleans have been replaced by a state variable --- coreapi/TunnelManager.cc | 190 +++++++++++++++++++++------------------ coreapi/TunnelManager.hh | 15 ++-- 2 files changed, 113 insertions(+), 92 deletions(-) diff --git a/coreapi/TunnelManager.cc b/coreapi/TunnelManager.cc index 03f6923ca..77e26fb1b 100644 --- a/coreapi/TunnelManager.cc +++ b/coreapi/TunnelManager.cc @@ -97,32 +97,15 @@ RtpTransport *TunnelManager::createRtpTransport(int port){ void TunnelManager::startClient() { ms_message("TunnelManager: Starting tunnel client"); - if (mTunnelClient == NULL) { - mTunnelClient = new TunnelClient(); - mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this); - list::iterator it; - for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){ - const ServerAddr &addr=*it; - mTunnelClient->addServer(addr.mAddr.c_str(), addr.mPort); - } - mTunnelClient->setHttpProxy(mHttpProxyHost.c_str(), mHttpProxyPort, mHttpUserName.c_str(), mHttpPasswd.c_str()); + mTunnelClient = new TunnelClient(); + mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this); + list::iterator it; + for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){ + const ServerAddr &addr=*it; + mTunnelClient->addServer(addr.mAddr.c_str(), addr.mPort); } + mTunnelClient->setHttpProxy(mHttpProxyHost.c_str(), mHttpProxyPort, mHttpUserName.c_str(), mHttpPasswd.c_str()); mTunnelClient->start(); - linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories); - if(mTunnelizeSipPackets) { - sal_enable_tunnel(mCore->sal, mTunnelClient); - } - mConnecting = true; -} - -void TunnelManager::stopClient(){ - ms_message("TunnelManager: Stopping tunnel client"); - linphone_core_set_rtp_transport_factories(mCore,NULL); - sal_disable_tunnel(mCore->sal); - if (mTunnelClient){ - delete mTunnelClient; - mTunnelClient=NULL; - } } bool TunnelManager::isConnected() const { @@ -151,9 +134,7 @@ TunnelManager::TunnelManager(LinphoneCore* lc) : mExosipTransport(NULL), #endif mMode(LinphoneTunnelModeDisable), - mAutoDetecting(false), - mConnecting(false), - mScheduledRegistration(false), + mState(disabled), mTunnelizeSipPackets(true), mTunnelClient(NULL), mHttpProxyPort(0), @@ -177,62 +158,94 @@ TunnelManager::~TunnelManager(){ for(UdpMirrorClientList::iterator udpMirror = mUdpMirrorClients.begin(); udpMirror != mUdpMirrorClients.end(); udpMirror++) { udpMirror->stop(); } - stopClient(); + if(mTunnelClient) delete mTunnelClient; linphone_core_remove_listener(mCore, mVTable); linphone_core_v_table_destroy(mVTable); } void TunnelManager::doRegistration(){ - if(mTunnelizeSipPackets) { - LinphoneProxyConfig* lProxy; - linphone_core_get_default_proxy(mCore, &lProxy); - if (lProxy) { - ms_message("TunnelManager: need to register"); - if(linphone_proxy_config_get_state(lProxy) != LinphoneRegistrationProgress) { - linphone_proxy_config_refresh_register(lProxy); - mScheduledRegistration = false; - } else { - ms_warning("TunnelManager: register difered. There is already a registration in progress"); - mScheduledRegistration = true; - } - } else { - mScheduledRegistration = false; - } + LinphoneProxyConfig* lProxy; + linphone_core_get_default_proxy(mCore, &lProxy); + if (lProxy) { + ms_message("TunnelManager: New registration"); + lProxy->commit = TRUE; + } +} + +void TunnelManager::doUnregistration() { + LinphoneProxyConfig *lProxy; + linphone_core_get_default_proxy(mCore, &lProxy); + if(lProxy) { + _linphone_proxy_config_unregister(lProxy); } } void TunnelManager::processTunnelEvent(const Event &ev){ if (ev.mData.mConnected){ - ms_message("Tunnel is connected"); - doRegistration(); + ms_message("TunnelManager: tunnel is connected"); + if(mState == connecting) { + linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories); + if(mTunnelizeSipPackets) { + doUnregistration(); + sal_enable_tunnel(mCore->sal, mTunnelClient); + doRegistration(); + } + mState = ready; + } } else { - ms_error("Tunnel has been disconnected"); + ms_error("TunnelManager: tunnel has been disconnected"); } - mConnecting = false; } void TunnelManager::setMode(LinphoneTunnelMode mode) { - if(mMode != mode) { - ms_message("TunnelManager: Switching mode from %s to %s", - tunnel_mode_to_string(mMode), - tunnel_mode_to_string(mode)); - switch(mode) { - case LinphoneTunnelModeEnable: - mMode = mode; + if(mMode == mode) return; + if((mode==LinphoneTunnelModeDisable && mState==disabled) + || (mode==LinphoneTunnelModeEnable && mState==ready)) { + return; + } + ms_message("TunnelManager: switching mode from %s to %s", + tunnel_mode_to_string(mMode), + tunnel_mode_to_string(mode)); + switch(mode) { + case LinphoneTunnelModeEnable: + if(mState == disabled) { startClient(); - break; - case LinphoneTunnelModeDisable: + mState = connecting; mMode = mode; - stopClient(); - doRegistration(); - break; - case LinphoneTunnelModeAuto: - mMode = mode; - autoDetect(); - break; - default: - ms_error("TunnelManager::setMode(): invalid mode (%d)", mode); + } else { + ms_error("TunnelManager: could not change mode. Bad state"); } + break; + case LinphoneTunnelModeDisable: + if(mState == ready) { + linphone_core_set_rtp_transport_factories(mCore,NULL); + if(mTunnelizeSipPackets) { + doUnregistration(); + sal_disable_tunnel(mCore->sal); + } + delete mTunnelClient; + mTunnelClient=NULL; + if(mTunnelizeSipPackets) { + doRegistration(); + } + mState = disabled; + mMode = mode; + } else { + ms_error("TunnelManager: could not change mode. Bad state"); + } + break; + case LinphoneTunnelModeAuto: + if(mState == disabled || mState == ready) { + if(startAutoDetection()) { + mState = autodetecting; + mMode = mode; + } + } else { + ms_error("TunnelManager: could not change mode. Bad state"); + } + break; + default: + ms_error("TunnelManager::setMode(): invalid mode (%d)", mode); } } @@ -244,10 +257,6 @@ void TunnelManager::tunnelCallback(bool connected, TunnelManager *zis){ } void TunnelManager::onIterate(){ - if(mScheduledRegistration) { - ms_message("Apply difered registration"); - doRegistration(); - } mMutex.lock(); while(!mEvq.empty()){ Event ev=mEvq.front(); @@ -313,22 +322,31 @@ LinphoneTunnelMode TunnelManager::getMode() const { } void TunnelManager::processUdpMirrorEvent(const Event &ev){ + if(mState != autodetecting) return; if (ev.mData.mHaveUdp) { - ms_message("TunnelManager: auto detection test succeed"); - stopClient(); - doRegistration(); - mAutoDetecting = false; + ms_message("TunnelManager: UDP mirror test succeed"); + if(mTunnelClient) { + if(mTunnelizeSipPackets) doUnregistration(); + delete mTunnelClient; + mTunnelClient = NULL; + if(mTunnelizeSipPackets) doRegistration(); + } + mState = disabled; } else { - ms_message("TunnelManager: auto detection test failed"); + ms_message("TunnelManager: UDP mirror test failed"); mCurrentUdpMirrorClient++; if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) { - ms_message("TunnelManager: trying another udp mirror"); + ms_message("TunnelManager: trying another UDP mirror"); UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient; lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this); } else { - ms_message("TunnelManager: all auto detection failed. Need ti enable tunnel"); - startClient(); - mAutoDetecting = false; + ms_message("TunnelManager: all UDP mirror tests failed"); + if(mTunnelClient==NULL) { + startClient(); + mState = connecting; + } else { + mState = ready; + } } } } @@ -349,24 +367,22 @@ void TunnelManager::sUdpMirrorClientCallback(bool isUdpAvailable, void* data) { void TunnelManager::networkReachableCb(LinphoneCore *lc, bool_t reachable) { TunnelManager *tunnel = bcTunnel(linphone_core_get_tunnel(lc)); - if(reachable && tunnel->getMode() == LinphoneTunnelModeAuto) { - tunnel->autoDetect(); + if(reachable && tunnel->getMode() == LinphoneTunnelModeAuto && tunnel->mState != connecting && tunnel->mState != autodetecting) { + tunnel->startAutoDetection(); + tunnel->mState = autodetecting; } } -void TunnelManager::autoDetect() { - if(mAutoDetecting) { - ms_error("TunnelManager: Cannot start auto detection. One auto detection is going on"); - return; - } +bool TunnelManager::startAutoDetection() { if (mUdpMirrorClients.empty()) { ms_error("TunnelManager: No UDP mirror server configured aborting auto detection"); - return; + return false; } + ms_message("TunnelManager: Starting auto-detection"); mCurrentUdpMirrorClient = mUdpMirrorClients.begin(); UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient; lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this); - mAutoDetecting = true; + return true; } void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd) { diff --git a/coreapi/TunnelManager.hh b/coreapi/TunnelManager.hh index 9b1a4c3a9..58475aab3 100644 --- a/coreapi/TunnelManager.hh +++ b/coreapi/TunnelManager.hh @@ -143,6 +143,13 @@ namespace belledonnecomm { bool isConnected() const; private: + enum State { + disabled, + connecting, + ready, + autodetecting + }; + enum EventType{ UdpMirrorClientEvent, TunnelEvent, @@ -168,9 +175,9 @@ namespace belledonnecomm { private: void onIterate(); void doRegistration(); + void doUnregistration(); void startClient(); - void stopClient(); - void autoDetect(); + bool startAutoDetection(); void processTunnelEvent(const Event &ev); void processUdpMirrorEvent(const Event &ev); void postEvent(const Event &ev); @@ -178,9 +185,7 @@ namespace belledonnecomm { private: LinphoneCore* mCore; LinphoneTunnelMode mMode; - bool mAutoDetecting; - bool mConnecting; - bool mScheduledRegistration; + State mState; bool mTunnelizeSipPackets; TunnelClient* mTunnelClient; std::string mHttpUserName;