Reworking TunnelManager

Some booleans have been replaced by a state variable
This commit is contained in:
François Grisez 2014-10-30 11:02:20 +01:00
parent de1f471a89
commit 636976e55d
2 changed files with 113 additions and 92 deletions

View file

@ -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<ServerAddr>::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<ServerAddr>::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) {

View file

@ -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;