/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Tizen.Applications;
namespace Tizen.Network.Connection
{
///
/// This is the ConnectionProfile class. It provides event and properties of the connection profile.
///
/// 3
public class ConnectionProfile : IDisposable
{
internal IntPtr ProfileHandle = IntPtr.Zero;
private IAddressInformation IPv4;
private IAddressInformation IPv6;
private bool disposed = false;
private EventHandler _ProfileStateChanged = null;
private Interop.ConnectionProfile.ProfileStateChangedCallback _profileChangedCallback;
private TizenSynchronizationContext context = new TizenSynchronizationContext();
internal IntPtr GetHandle()
{
return ProfileHandle;
}
///
/// The event is called when the state of profile is changed.
///
/// 3
/// http://tizen.org/feature/network.ethernet
/// http://tizen.org/feature/network.telephony
/// http://tizen.org/feature/network.tethering.bluetooth
/// http://tizen.org/feature/network.wifi
/// Thrown when a feature is not supported.
public event EventHandler ProfileStateChanged
{
add
{
Log.Debug(Globals.LogTag, "ProfileStateChanged add");
context.Post((x) =>
{
if (_ProfileStateChanged == null)
{
ProfileStateChangedStart();
}
_ProfileStateChanged += value;
}, null);
}
remove
{
Log.Debug(Globals.LogTag, "ProfileStateChanged remove");
context.Post((x) =>
{
_ProfileStateChanged -= value;
if (_ProfileStateChanged == null)
{
ProfileStateChangedStop();
}
}, null);
}
}
private void ProfileStateChangedStart()
{
_profileChangedCallback = (ProfileState state, IntPtr userData) =>
{
Log.Info(Globals.LogTag, "***** MOON ProfileStateChanged occur");
if (_ProfileStateChanged != null)
{
_ProfileStateChanged(null, new ProfileStateEventArgs(state));
}
};
Log.Debug(Globals.LogTag, "ProfileStateChangedStart");
int ret = Interop.ConnectionProfile.SetStateChangeCallback(ProfileHandle, _profileChangedCallback, IntPtr.Zero);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to register callback for changing profile state, " + (ConnectionError)ret);
}
}
private void ProfileStateChangedStop()
{
Log.Debug(Globals.LogTag, "ProfileStateChangedStop");
int ret = Interop.ConnectionProfile.UnsetStateChangeCallback(ProfileHandle);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to unregister callback for changing profile state, " + (ConnectionError)ret);
}
}
internal ConnectionProfile(IntPtr handle)
{
ProfileHandle = handle;
IPv4 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv4);
IPv6 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv6);
}
///
/// Destroy the ConnectionProfile object
///
~ConnectionProfile()
{
Dispose(false);
}
///
/// Disposes the memory allocated to unmanaged resources.
///
/// 3
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
Log.Debug(Globals.LogTag, ">>> ConnectionProfile Dispose with " + disposing);
if (disposed)
return;
// Free unmanaged objects
UnregisterEvents();
Destroy();
disposed = true;
}
private void UnregisterEvents()
{
if (_ProfileStateChanged != null)
{
ProfileStateChangedStop();
}
}
private void Destroy()
{
Interop.ConnectionProfile.Destroy(ProfileHandle);
ProfileHandle = IntPtr.Zero;
}
internal void CheckDisposed()
{
if (disposed)
{
throw new ObjectDisposedException(GetType().FullName);
}
}
///
/// The profile ID.
///
/// 3
/// Unique ID of the profile.
public string Id
{
get
{
IntPtr Value;
int ret = Interop.ConnectionProfile.GetId(ProfileHandle, out Value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get id of connection profile, " + (ConnectionError)ret);
}
string result = Marshal.PtrToStringAnsi(Value);
Interop.Libc.Free(Value);
return result;
}
}
///
/// The profile name.
///
/// 3
/// User friendly name of the profile.
public string Name
{
get
{
IntPtr Value;
int ret = Interop.ConnectionProfile.GetName(ProfileHandle, out Value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get name of connection profile, " + (ConnectionError)ret);
}
string result = Marshal.PtrToStringAnsi(Value);
Interop.Libc.Free(Value);
return result;
}
}
///
/// The network type.
///
/// 3
/// Profile type of the network connection.
public ConnectionProfileType Type
{
get
{
int Value;
int ret = Interop.ConnectionProfile.GetType(ProfileHandle, out Value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get type of connection profile, " + (ConnectionError)ret);
}
return (ConnectionProfileType)Value;
}
}
///
/// The name of the network interface.
///
/// 3
/// Network interface name, for example, eth0 and pdp0.
public string InterfaceName
{
get
{
IntPtr Value;
int ret = Interop.ConnectionProfile.GetNetworkInterfaceName(ProfileHandle, out Value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
}
string result = Marshal.PtrToStringAnsi(Value);
Interop.Libc.Free(Value);
return result;
}
}
///
/// Refreshes the profile information.
///
/// 3
/// http://tizen.org/privilege/network.get
/// http://tizen.org/feature/network.ethernet
/// http://tizen.org/feature/network.telephony
/// http://tizen.org/feature/network.tethering.bluetooth
/// http://tizen.org/feature/network.wifi
/// Thrown when a feature is not supported.
/// Thrown when a permission is denied.
/// Thrown when a value is an invalid parameter.
/// Thrown when a profile instance is invalid or when a method fails due to an invalid operation.
/// Thrown when an operation is performed on a disposed object.
public void Refresh()
{
CheckDisposed();
int ret = Interop.ConnectionProfile.Refresh(ProfileHandle);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
ConnectionErrorFactory.ThrowConnectionException(ret);
}
}
///
/// Gets the network state.
///
/// 3
/// The address family.
/// The network state.
/// http://tizen.org/feature/network.ethernet
/// http://tizen.org/feature/network.telephony
/// http://tizen.org/feature/network.tethering.bluetooth
/// http://tizen.org/feature/network.wifi
/// Thrown when a feature is not supported.
/// Thrown when a value is an invalid parameter.
/// Thrown when a profile instance is invalid or when a method fails due to an invalid operation.
/// Thrown when an operation is performed on a disposed object.
public ProfileState GetState(AddressFamily family)
{
CheckDisposed();
int Value;
int ret = (int)ConnectionError.None;
if (family == AddressFamily.IPv4)
{
ret = Interop.ConnectionProfile.GetState(ProfileHandle, out Value);
}
else
{
ret = Interop.ConnectionProfile.GetIPv6State(ProfileHandle, out Value);
}
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get profile state, " + (ConnectionError)ret);
ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
ConnectionErrorFactory.ThrowConnectionException(ret);
}
return (ProfileState)Value;
}
///
/// The Proxy type.
///
/// 3
/// Proxy type of the connection.
/// Thrown during set when a feature is not supported.
/// Thrown during set when a value is an invalid parameter.
/// Thrown during set when a profile instance is invalid or when a method fails due to an invalid operation.
/// Thrown during set when a operation is performed on a disposed object.
public ProxyType ProxyType
{
get
{
int Value;
int ret = Interop.ConnectionProfile.GetProxyType(ProfileHandle, out Value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get proxy type, " + (ConnectionError)ret);
}
return (ProxyType)Value;
}
set
{
CheckDisposed();
int ret = Interop.ConnectionProfile.SetProxyType(ProfileHandle, (int)value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to set proxy type, " + (ConnectionError)ret);
ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
ConnectionErrorFactory.ThrowConnectionException(ret);
}
}
}
///
/// The proxy address.
///
/// 3
/// Proxy address of the connection.
/// Thrown during set when a feature is not supported.
/// Thrown during set when a value is an invalid parameter.
/// Thrown during set when a value is null.
/// Thrown during set when a profile instance is invalid or when a method fails due to an invalid operation.
/// Thrown when an operation is performed on a disposed object.
public string ProxyAddress
{
get
{
IntPtr Value;
int ret = Interop.ConnectionProfile.GetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, out Value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to get proxy address, " + (ConnectionError)ret);
}
string result = Marshal.PtrToStringAnsi(Value);
Interop.Libc.Free(Value);
return result;
}
set
{
CheckDisposed();
if (value != null)
{
int ret = Interop.ConnectionProfile.SetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, value);
if ((ConnectionError)ret != ConnectionError.None)
{
Log.Error(Globals.LogTag, "It failed to set proxy address, " + (ConnectionError)ret);
ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
ConnectionErrorFactory.ThrowConnectionException(ret);
}
}
else
{
throw new ArgumentNullException("ProxyAddress is null");
}
}
}
///
/// The address information (IPv4).
///
/// 3
/// Instance of IAddressInformation with IPV4 address.
public IAddressInformation IPv4Settings
{
get
{
return IPv4;
}
}
///
/// The address information (IPv6).
///
/// 3
/// Instance of IAddressInformation with IPV6 address.
public IAddressInformation IPv6Settings
{
get
{
return IPv6;
}
}
}
///
/// An extended EventArgs class, which contains changed profile state.
///
/// 3
public class ProfileStateEventArgs : EventArgs
{
private ProfileState _State = ProfileState.Disconnected;
internal ProfileStateEventArgs(ProfileState state)
{
_State = state;
}
///
/// The profile state.
///
/// 3
/// State type of the connection profile.
public ProfileState State
{
get
{
return _State;
}
}
}
}