Commit 33613f0f authored by Ghislain MARY's avatar Ghislain MARY

Handle tunnel settings.

parent db0bfb00
......@@ -147,6 +147,7 @@ popd</Command>
<ClInclude Include="Enums.h" />
<ClInclude Include="PayloadType.h" />
<ClInclude Include="Server.h" />
<ClInclude Include="Tunnel.h" />
<ClInclude Include="Utils.h" />
</ItemGroup>
<ItemGroup>
......@@ -165,6 +166,7 @@ popd</Command>
<ClCompile Include="LinphoneProxyConfig.cpp" />
<ClCompile Include="LpConfig.cpp" />
<ClCompile Include="PayloadType.cpp" />
<ClCompile Include="Tunnel.cpp" />
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<ItemGroup>
......
......@@ -9,6 +9,7 @@
#include "LpConfig.h"
#include "PayloadType.h"
#include "CallController.h"
#include "Tunnel.h"
#include "Server.h"
#include "Enums.h"
#include "ApiLock.h"
......@@ -802,76 +803,19 @@ Platform::Boolean Linphone::Core::LinphoneCore::IsMediaEncryptionMandatory()
return linphone_core_is_media_encryption_mandatory(this->lc);
}
void Linphone::Core::LinphoneCore::EnableTunnel(Platform::Boolean enable)
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
LinphoneTunnel* tunnel = linphone_core_get_tunnel(this->lc);
if (tunnel == nullptr)
return;
linphone_tunnel_enable(tunnel, enable);
}
void Linphone::Core::LinphoneCore::TunnelAutoDetect()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
LinphoneTunnel* tunnel = linphone_core_get_tunnel(this->lc);
if (tunnel == nullptr)
return;
linphone_tunnel_auto_detect(tunnel);
}
void Linphone::Core::LinphoneCore::TunnelCleanServers()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
LinphoneTunnel* tunnel = linphone_core_get_tunnel(this->lc);
if (tunnel == nullptr)
return;
linphone_tunnel_clean_servers(tunnel);
}
void Linphone::Core::LinphoneCore::TunnelSetHttpProxy(Platform::String^ host, int port, Platform::String^ username, Platform::String^ password)
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
LinphoneTunnel* tunnel = linphone_core_get_tunnel(this->lc);
if (tunnel == nullptr)
return;
const char* h = Linphone::Core::Utils::pstoccs(host);
const char* u = Linphone::Core::Utils::pstoccs(username);
const char* pwd = Linphone::Core::Utils::pstoccs(password);
linphone_tunnel_set_http_proxy(tunnel, h, port, u, pwd);
delete(h);
delete(u);
delete(pwd);
}
void Linphone::Core::LinphoneCore::TunnelAddServerAndMirror(Platform::String^ host, int port, int udpMirrorPort, int roundTripDelay)
Platform::Boolean Linphone::Core::LinphoneCore::IsTunnelAvailable()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
LinphoneTunnel* tunnel = linphone_core_get_tunnel(this->lc);
if (tunnel == nullptr)
return;
const char* h = Linphone::Core::Utils::pstoccs(host);
//TODO
//LinphoneTunnelConfig* config = linphone_tunnel_config_new();
//linphone_tunnel_config_set_host(config, h);
//linphone_tunnel_config_set_port(config, port);
//linphone_tunnel_config_set_delay(config, roundTripDelay);
//linphone_tunnel_config_set_remote_udp_mirror_port(config, udpMirrorPort);
//linphone_tunnel_add_server(linphone_core_get_tunnel(this->lc), config);
delete(h);
return linphone_core_tunnel_available();
}
Platform::Boolean Linphone::Core::LinphoneCore::IsTunnelAvailable()
Linphone::Core::Tunnel^ Linphone::Core::LinphoneCore::GetTunnel()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
return linphone_core_tunnel_available();
LinphoneTunnel *lt = linphone_core_get_tunnel(this->lc);
if (lt == nullptr)
return nullptr;
return ref new Linphone::Core::Tunnel(lt);
}
void Linphone::Core::LinphoneCore::SetUserAgent(Platform::String^ name, Platform::String^ version)
......
......@@ -22,6 +22,7 @@ namespace Linphone
ref class LinphoneCallStats;
ref class PayloadType;
ref class LpConfig;
ref class Tunnel;
/// <summary>
/// Signaling transports ports
......@@ -420,17 +421,8 @@ namespace Linphone
void SetMediaEncryptionMandatory(Platform::Boolean yesno);
Platform::Boolean IsMediaEncryptionMandatory();
void EnableTunnel(Platform::Boolean enable);
void TunnelAutoDetect();
void TunnelCleanServers();
void TunnelSetHttpProxy(Platform::String^ host, int port, Platform::String^ username, Platform::String^ password);
/// <param name="host">Tunnel server IP address</param>
/// <param name="port">Tunnel server TLS port, recommended value is 443</param>
/// <param name="udpMirrorPort">Remote port on the tunnel server side used to test UDP reachability</param>
/// <param name="roundTripDelay">UDP packet round trip delay in ms considered as acceptable. Recommended value is 1000 ms.</param>
void TunnelAddServerAndMirror(Platform::String^ host, int port, int udpMirrorPort, int roundTripDelay);
Platform::Boolean IsTunnelAvailable();
Tunnel^ GetTunnel();
void SetUserAgent(Platform::String^ name, Platform::String^ version);
void SetCPUCount(int count);
......
#include "Tunnel.h"
#include "Server.h"
#include "Enums.h"
#include "ApiLock.h"
#include <collection.h>
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
Linphone::Core::TunnelConfig::TunnelConfig(Platform::String^ host, int port, int udpMirrorPort, int roundTripDelay) :
host(host),
port(port),
udpMirrorPort(udpMirrorPort),
roundTripDelay(roundTripDelay)
{
}
Platform::String^ Linphone::Core::TunnelConfig::Host::get()
{
return this->host;
}
void Linphone::Core::TunnelConfig::Host::set(Platform::String^ value)
{
this->host = value;
}
int Linphone::Core::TunnelConfig::Port::get()
{
return this->port;
}
void Linphone::Core::TunnelConfig::Port::set(int value)
{
this->port = value;
}
int Linphone::Core::TunnelConfig::UdpMirrorPort::get()
{
return this->udpMirrorPort;
}
void Linphone::Core::TunnelConfig::UdpMirrorPort::set(int value)
{
this->udpMirrorPort = value;
}
int Linphone::Core::TunnelConfig::RoundTripDelay::get()
{
return this->roundTripDelay;
}
void Linphone::Core::TunnelConfig::RoundTripDelay::set(int value)
{
this->roundTripDelay = value;
}
Platform::String^ Linphone::Core::TunnelConfig::ToString()
{
return "host[" + this->host + "] port[" + this->port + "] udpMirrorPort[" + this->udpMirrorPort + "] roundTripDelay[" + this->roundTripDelay + "]";
}
Linphone::Core::Tunnel::Tunnel(::LinphoneTunnel *tunnel) :
lt(tunnel)
{
}
Linphone::Core::Tunnel::~Tunnel()
{
}
Platform::Boolean Linphone::Core::Tunnel::IsEnabled()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
return linphone_tunnel_enabled(this->lt);
}
void Linphone::Core::Tunnel::Enable(Platform::Boolean enable)
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
linphone_tunnel_enable(this->lt, enable);
}
void Linphone::Core::Tunnel::AutoDetect()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
linphone_tunnel_auto_detect(this->lt);
}
static void AddServerConfigToVector(void *vServerConfig, void *vector)
{
::LinphoneTunnelConfig *pc = (LinphoneTunnelConfig *)vServerConfig;
Linphone::Core::RefToPtrProxy<IVector<Object^>^> *list = reinterpret_cast< Linphone::Core::RefToPtrProxy<IVector<Object^>^> *>(vector);
IVector<Object^>^ serverconfigs = (list) ? list->Ref() : nullptr;
const char *chost = linphone_tunnel_config_get_host(pc);
int port = linphone_tunnel_config_get_port(pc);
int udpMirrorPort = linphone_tunnel_config_get_remote_udp_mirror_port(pc);
int roundTripDelay = linphone_tunnel_config_get_delay(pc);
Linphone::Core::TunnelConfig^ serverConfig = ref new Linphone::Core::TunnelConfig(Linphone::Core::Utils::cctops(chost), port, udpMirrorPort, roundTripDelay);
serverconfigs->Append(serverConfig);
}
IVector<Object^>^ Linphone::Core::Tunnel::GetServers()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
IVector<Object^>^ serverconfigs = ref new Vector<Object^>();
const MSList *configList = linphone_tunnel_get_servers(this->lt);
RefToPtrProxy<IVector<Object^>^> *serverConfigPtr = new RefToPtrProxy<IVector<Object^>^>(serverconfigs);
ms_list_for_each2(configList, AddServerConfigToVector, serverConfigPtr);
return serverconfigs;
}
void Linphone::Core::Tunnel::CleanServers()
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
linphone_tunnel_clean_servers(this->lt);
}
void Linphone::Core::Tunnel::SetHttpProxy(Platform::String^ host, int port, Platform::String^ username, Platform::String^ password)
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
const char* h = Linphone::Core::Utils::pstoccs(host);
const char* u = Linphone::Core::Utils::pstoccs(username);
const char* pwd = Linphone::Core::Utils::pstoccs(password);
linphone_tunnel_set_http_proxy(this->lt, h, port, u, pwd);
delete(h);
delete(u);
delete(pwd);
}
void Linphone::Core::Tunnel::AddServer(Platform::String^ host, int port)
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
const char* h = Linphone::Core::Utils::pstoccs(host);
LinphoneTunnelConfig* config = linphone_tunnel_config_new();
linphone_tunnel_config_set_host(config, h);
linphone_tunnel_config_set_port(config, port);
linphone_tunnel_add_server(this->lt, config);
delete(h);
}
void Linphone::Core::Tunnel::AddServer(Platform::String^ host, int port, int udpMirrorPort, int roundTripDelay)
{
std::lock_guard<std::recursive_mutex> lock(g_apiLock);
const char* h = Linphone::Core::Utils::pstoccs(host);
LinphoneTunnelConfig* config = linphone_tunnel_config_new();
linphone_tunnel_config_set_host(config, h);
linphone_tunnel_config_set_port(config, port);
linphone_tunnel_config_set_delay(config, roundTripDelay);
linphone_tunnel_config_set_remote_udp_mirror_port(config, udpMirrorPort);
linphone_tunnel_add_server(this->lt, config);
delete(h);
}
#pragma once
#include "Enums.h"
#include "Utils.h"
#include "coreapi\linphone_tunnel.h"
namespace Linphone
{
namespace Core
{
ref class LinphoneCore;
/// <summary>
/// Tunnel server configuration.
/// </summary>
public ref class TunnelConfig sealed
{
public:
TunnelConfig(Platform::String^ host, int port, int udpMirrorPort, int roundTripDelay);
Platform::String^ ToString();
property Platform::String^ Host
{
Platform::String^ get();
void set(Platform::String^ value);
}
property int Port
{
int get();
void set(int value);
}
property int UdpMirrorPort
{
int get();
void set(int value);
}
property int RoundTripDelay
{
int get();
void set(int value);
}
private:
Platform::String^ host;
int port;
int udpMirrorPort;
int roundTripDelay;
};
/// <summary>
/// Main object obtained by LinphoneCore.GetTunnel()
/// </summary>
public ref class Tunnel sealed
{
public:
/// <summary>
/// Tells whether the tunnel is enabled or not.
/// </summary>
bool IsEnabled();
/// <summary>
/// Enable/disable the tunnel.
/// </summary>
void Enable(Platform::Boolean enable);
/// <summary>
/// Start tunnel need detection.
/// </summary>
void AutoDetect();
/// <summary>
/// Returns an IList&lt;Object&gt; where each object is a TunnelConfig.
/// </summary>
Windows::Foundation::Collections::IVector<Platform::Object^>^ GetServers();
/// <summary>
/// Removes all tunnel server addresses previously entered with AddServer().
/// </summary>
void CleanServers();
/// <summary>
/// Set an optional http proxy to go through when connecting to tunnel server.
/// <param name="host">Http proxy host</param>
/// <param name="port">Http proxy port</param>
/// <param name="username">Optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use null if not needed.</param>
/// <param name="password">Optional http proxy password. Use null if not needed.</param>
/// </summary>
void SetHttpProxy(Platform::String^ host, int port, Platform::String^ username, Platform::String^ password);
/// <summary>
/// Add a server to the tunnel configuration
/// </summary>
/// <param name="host">Tunnel server IP address</param>
/// <param name="port">Tunnel server TLS port, recommended value is 443</param>
void AddServer(Platform::String^ host, int port);
/// <summary>
/// Add a server to the tunnel configuration
/// </summary>
/// <param name="host">Tunnel server IP address</param>
/// <param name="port">Tunnel server TLS port, recommended value is 443</param>
/// <param name="udpMirrorPort">Remote port on the tunnel server side used to test UDP reachability</param>
/// <param name="roundTripDelay">UDP packet round trip delay in ms considered as acceptable. Recommended value is 1000 ms.</param>
void AddServer(Platform::String^ host, int port, int udpMirrorPort, int roundTripDelay);
private:
friend ref class Linphone::Core::LinphoneCore;
Tunnel(::LinphoneTunnel *tunnel);
~Tunnel();
::LinphoneTunnel *lt;
};
}
}
\ No newline at end of file
......@@ -30,6 +30,7 @@ namespace Linphone.Model
{
protected Dictionary<String, String> dict;
protected Dictionary<String, String> changesDict;
protected const string ApplicationSection = "app";
/// <summary>
/// Public constructor.
......@@ -154,7 +155,6 @@ namespace Linphone.Model
/// </summary>
public class ApplicationSettingsManager : SettingsManager, ISettingsManager
{
private const string ApplicationSection = "app";
private LpConfig Config;
#region Constants settings names
......@@ -760,6 +760,10 @@ namespace Linphone.Model
/// </summary>
public class NetworkSettingsManager : SettingsManager, ISettingsManager
{
private LpConfig Config;
private Dictionary<string, string> TunnelModeToString;
private Dictionary<string, string> StringToTunnelMode;
#region Constants settings names
private const string SIPTransportSettingKeyName = "SIPTransport";
private const string SIPPortKeyName = "SIPPort";
......@@ -768,6 +772,35 @@ namespace Linphone.Model
private const string TunnelModeKeyName = "TunnelMode";
#endregion
/// <summary>
/// Public constructor.
/// </summary>
public NetworkSettingsManager()
{
if (LinphoneManager.Instance.LinphoneCore == null)
{
Config = LinphoneManager.Instance.LinphoneCoreFactory.CreateLpConfig(GetConfigPath(), GetFactoryConfigPath());
}
else
{
Config = LinphoneManager.Instance.LinphoneCore.GetConfig();
}
TunnelModeToString = new Dictionary<string, string>()
{
{ AppResources.TunnelMode3GOnly, "3gonly" },
{ AppResources.TunnelModeAlways, "always" },
{ AppResources.TunnelModeAuto, "auto" },
{ AppResources.TunnelModeDisabled, "disabled" }
};
StringToTunnelMode = new Dictionary<string, string>()
{
{ "3gonly", AppResources.TunnelMode3GOnly },
{ "always", AppResources.TunnelModeAlways },
{ "auto", AppResources.TunnelModeAuto },
{ "disabled", AppResources.TunnelModeDisabled }
};
}
#region Implementation of the ISettingsManager interface
/// <summary>
/// Load the network settings.
......@@ -794,6 +827,27 @@ namespace Linphone.Model
}
dict[SIPTransportSettingKeyName] = tname;
dict[SIPPortKeyName] = port.ToString();
// Load tunnel configuration
dict[TunnelModeKeyName] = AppResources.TunnelModeDisabled;
dict[TunnelServerKeyName] = "";
dict[TunnelPortKeyName] = "";
if (LinphoneManager.Instance.LinphoneCore.IsTunnelAvailable())
{
String mode = Config.GetString(ApplicationSection, TunnelModeKeyName, TunnelModeToString[AppResources.TunnelModeDisabled]);
dict[TunnelModeKeyName] = StringToTunnelMode[mode];
Tunnel tunnel = LinphoneManager.Instance.LinphoneCore.GetTunnel();
if (tunnel != null)
{
IList<Object> servers = tunnel.GetServers();
if (servers.Count > 0)
{
TunnelConfig conf = servers[0] as TunnelConfig;
dict[TunnelServerKeyName] = conf.Host;
dict[TunnelPortKeyName] = conf.Port.ToString();
}
}
}
}
/// <summary>
......@@ -819,6 +873,24 @@ namespace Linphone.Model
}
LinphoneManager.Instance.LinphoneCore.SetSignalingTransportsPorts(transports);
}
// Save tunnel configuration
if (LinphoneManager.Instance.LinphoneCore.IsTunnelAvailable())
{
if (ValueChanged(TunnelServerKeyName) || ValueChanged(TunnelPortKeyName))
{
Tunnel tunnel = LinphoneManager.Instance.LinphoneCore.GetTunnel();
if (tunnel != null)
{
tunnel.CleanServers();
tunnel.AddServer(GetNew(TunnelServerKeyName), Convert.ToInt32(GetNew(TunnelPortKeyName)));
}
}
if (ValueChanged(TunnelModeKeyName))
{
Config.SetString(ApplicationSection, TunnelModeKeyName, TunnelModeToString[GetNew(TunnelModeKeyName)]);
}
}
}
#endregion
......@@ -845,11 +917,11 @@ namespace Linphone.Model
{
get
{
return ""; // TODO
return Get(TunnelServerKeyName);
}
set
{
// TODO
Set(TunnelServerKeyName, value);
}
}
......@@ -860,11 +932,11 @@ namespace Linphone.Model
{
get
{
return ""; // TODO
return Get(TunnelPortKeyName);
}
set
{
// TODO
Set(TunnelPortKeyName, value);
}
}
......@@ -875,11 +947,11 @@ namespace Linphone.Model
{
get
{
return AppResources.TunnelModeDisabled; // TODO
return Get(TunnelModeKeyName);
}
set
{
// TODO
Set(TunnelModeKeyName, value);
}
}
#endregion
......
......@@ -64,6 +64,8 @@
<ActivatableClass ActivatableClassId="Linphone.Core.PayloadType" ThreadingModel="MTA" />
<ActivatableClass ActivatableClassId="Linphone.Core.LinphoneProxyConfig" ThreadingModel="MTA" />
<ActivatableClass ActivatableClassId="Linphone.Core.LpConfig" ThreadingModel="MTA" />
<ActivatableClass ActivatableClassId="Linphone.Core.TunnelConfig" ThreadingModel="MTA" />
<ActivatableClass ActivatableClassId="Linphone.Core.Tunnel" ThreadingModel="MTA" />
</InProcessServer>
<OutOfProcessServer ServerName="Linphone.Core">
<Path>Linphone.Core.DLL</Path>
......@@ -93,6 +95,9 @@
<Interface Name="Linphone.Core.__IPayloadTypePublicNonVirtuals" InterfaceId="{BF73ED50-6AF0-3E18-9C7B-F81A8E91287B}" />
<Interface Name="Linphone.Core.__ILinphoneProxyConfigPublicNonVirtuals" InterfaceId="{FD2DF2D0-E760-354B-AD77-D0C81FBACE0B}" />
<Interface Name="Linphone.Core.__ILpConfigPublicNonVirtuals" InterfaceId="{3D421643-A4D5-370B-BA94-D03ED034EE76}" />
<Interface Name="Linphone.Core.__ITunnelConfigPublicNonVirtuals" InterfaceId="{68700A9B-6D1E-3167-B4AA-626894473735}" />
<Interface Name="Linphone.Core.__ITunnelConfigFactory" InterfaceId="{EE452863-F4DB-3CAF-B716-854C8EF40E25}" />
<Interface Name="Linphone.Core.__ITunnelPublicNonVirtuals" InterfaceId="{A04D28B9-616C-3870-B1AA-31747C3704F8}" />
</ProxyStub>
</ActivatableClasses>
<ScreenResolutions>
......
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