Fix Dispose to release native resources only when Dispose is explicitly called
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Connection / Tizen.Network.Connection / ConnectionProfile.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Text;
21 using System.Runtime.InteropServices;
22
23 namespace Tizen.Network.Connection
24 {
25     /// <summary>
26     /// This Class is ConnectionProfile
27     /// </summary>
28     public class ConnectionProfile : IDisposable
29     {
30         internal IntPtr ProfileHandle = IntPtr.Zero;
31         private IAddressInformation Ipv4;
32         private IAddressInformation Ipv6;
33         private bool disposed = false;
34         private EventHandler _ProfileStateChanged;
35
36         internal IntPtr GetHandle()
37         {
38             return ProfileHandle;
39         }
40
41         /// <summary>
42         /// The event that is called when the state of profile is changed.
43         /// </summary>
44         public event EventHandler ProfileStateChanged
45         {
46             add
47             {
48                 if (_ProfileStateChanged == null)
49                 {
50                     ProfileStateChangedStart();
51                 }
52                 _ProfileStateChanged += value;
53             }
54             remove
55             {
56                 _ProfileStateChanged -= value;
57                 if (_ProfileStateChanged == null)
58                 {
59                     ProfileStateChangedStop();
60                 }
61             }
62         }
63
64         private void TypeChangedCallback(ProfileState state, IntPtr userData)
65         {
66             if (_ProfileStateChanged != null)
67             {
68                 _ProfileStateChanged(null, new ProfileStateEventArgs(state));
69             }
70         }
71
72         private void ProfileStateChangedStart()
73         {
74             int ret = Interop.ConnectionProfile.SetStateChangeCallback(ProfileHandle, TypeChangedCallback, IntPtr.Zero);
75             if ((ConnectionError)ret != ConnectionError.None)
76             {
77                 Log.Error(Globals.LogTag, "It failed to register callback for changing profile state, " + (ConnectionError)ret);
78             }
79         }
80
81         private void ProfileStateChangedStop()
82         {
83             int ret = Interop.ConnectionProfile.UnsetStateChangeCallback(ProfileHandle);
84             if ((ConnectionError)ret != ConnectionError.None)
85             {
86                 Log.Error(Globals.LogTag, "It failed to unregister callback for changing profile state, " + (ConnectionError)ret);
87             }
88         }
89
90         internal ConnectionProfile(IntPtr handle)
91         {
92             ProfileHandle = handle;
93             Ipv4 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.Ipv4);
94             Ipv6 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.Ipv6);
95         }
96
97         ~ConnectionProfile()
98         {
99             Dispose(false);
100         }
101
102         public void Dispose()
103         {
104             Dispose(true);
105             GC.SuppressFinalize(this);
106         }
107
108         private void Dispose(bool disposing)
109         {
110             Log.Debug(Globals.LogTag, ">>> ConnectionProfile Dispose with " + disposing);
111             if (disposed)
112                 return;
113
114             if (disposing)
115             {
116                 // Free managed objects.
117                 UnregisterEvents();
118                 Destroy();
119             }
120             disposed = true;
121         }
122
123         private void UnregisterEvents()
124         {
125             if (_ProfileStateChanged != null)
126             {
127                 ProfileStateChangedStop();
128             }
129         }
130
131         private void Destroy()
132         {
133             Interop.ConnectionProfile.Destroy(ProfileHandle);
134         }
135
136         /// <summary>
137         /// Gets the profile ID.
138         /// </summary>
139         public string Id
140         {
141             get
142             {
143                 IntPtr Value;
144                 int ret = Interop.ConnectionProfile.GetId(ProfileHandle, out Value);
145                 if ((ConnectionError)ret != ConnectionError.None)
146                 {
147                     Log.Error(Globals.LogTag, "It failed to get id of connection profile, " + (ConnectionError)ret);
148                 }
149                 string result = Marshal.PtrToStringAnsi(Value);
150                 Interop.Libc.Free(Value);
151                 return result;
152             }
153         }
154
155         /// <summary>
156         /// Gets the profile name.
157         /// </summary>
158         /// <privilege>http://tizen.org/privilege/network.get</privilege>
159         public string Name
160         {
161             get
162             {
163                 IntPtr Value;
164                 int ret = Interop.ConnectionProfile.GetName(ProfileHandle, out Value);
165                 if ((ConnectionError)ret != ConnectionError.None)
166                 {
167                     Log.Error(Globals.LogTag, "It failed to get name of connection profile, " + (ConnectionError)ret);
168                 }
169                 string result = Marshal.PtrToStringAnsi(Value);
170                 Interop.Libc.Free(Value);
171                 return result;
172             }
173         }
174
175         /// <summary>
176         /// Gets the network type.
177         /// </summary>
178         public ConnectionProfileType Type
179         {
180             get
181             {
182                 int Value;
183                 int ret = Interop.ConnectionProfile.GetType(ProfileHandle, out Value);
184                 if ((ConnectionError)ret != ConnectionError.None)
185                 {
186                     Log.Error(Globals.LogTag, "It failed to get type of connection profile, " + (ConnectionError)ret);
187                 }
188                 return (ConnectionProfileType)Value;
189             }
190         }
191
192         /// <summary>
193         /// Gets the name of the network interface, e.g. eth0 and pdp0.
194         /// </summary>
195         public string InterfaceName
196         {
197             get
198             {
199                 IntPtr Value;
200                 int ret = Interop.ConnectionProfile.GetNetworkInterfaceName(ProfileHandle, out Value);
201                 if ((ConnectionError)ret != ConnectionError.None)
202                 {
203                     Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
204                 }
205                 string result = Marshal.PtrToStringAnsi(Value);
206                 Interop.Libc.Free(Value);
207                 return result;
208             }
209         }
210
211         /// <summary>
212         /// Gets the profile state.
213         /// </summary>
214         public ProfileState State
215         {
216             get
217             {
218                 int Value;
219                 int ret = Interop.ConnectionProfile.GetState(ProfileHandle, out Value);
220                 if ((ConnectionError)ret != ConnectionError.None)
221                 {
222                     Log.Error(Globals.LogTag, "It failed to get profile state, " + (ConnectionError)ret);
223                 }
224                 return (ProfileState)Value;
225             }
226         }
227
228         /// <summary>
229         /// Gets the Proxy type.
230         /// </summary>
231         public ProxyType ProxyType
232         {
233             get
234             {
235                 int Value;
236                 int ret = Interop.ConnectionProfile.GetProxyType(ProfileHandle, out Value);
237                 if ((ConnectionError)ret != ConnectionError.None)
238                 {
239                     Log.Error(Globals.LogTag, "It failed to get proxy type, " + (ConnectionError)ret);
240                 }
241                 return (ProxyType)Value;
242
243             }
244             set
245             {
246                 int ret = Interop.ConnectionProfile.SetProxyType(ProfileHandle, (int)value);
247                 if ((ConnectionError)ret != ConnectionError.None)
248                 {
249                     Log.Error(Globals.LogTag, "It failed to set proxy type, " + (ConnectionError)ret);
250                     ConnectionErrorFactory.ThrowConnectionException(ret);
251                 }
252             }
253         }
254
255         /// <summary>
256         /// The proxy address.
257         /// </summary>
258         public String ProxyAddress
259         {
260             get
261             {
262                 IntPtr Value;
263                 int ret = Interop.ConnectionProfile.GetProxyAddress(ProfileHandle, (int)AddressFamily.Ipv4, out Value);
264                 if ((ConnectionError)ret != ConnectionError.None)
265                 {
266                     Log.Error(Globals.LogTag, "It failed to get proxy address, " + (ConnectionError)ret);
267                 }
268                 string result = Marshal.PtrToStringAnsi(Value);
269                 Interop.Libc.Free(Value);
270                 return result;
271
272             }
273             set
274             {
275                 int ret = Interop.ConnectionProfile.SetProxyAddress(ProfileHandle, (int)AddressFamily.Ipv4, value.ToString());
276                 if ((ConnectionError)ret != ConnectionError.None)
277                 {
278                     Log.Error(Globals.LogTag, "It failed to set proxy address, " + (ConnectionError)ret);
279                     ConnectionErrorFactory.ThrowConnectionException(ret);
280                 }
281             }
282         }
283
284         /// <summary>
285         /// The subnet mask address(Ipv4).
286         /// </summary>
287         public IAddressInformation Ipv4Settings
288         {
289             get
290             {
291                 return Ipv4;
292
293             }
294         }
295
296         /// <summary>
297         /// The subnet mask address(Ipv4).
298         /// </summary>
299         public IAddressInformation Ipv6Settings
300         {
301             get
302             {
303                 return Ipv6;
304             }
305         }
306     }
307
308     /// <summary>
309     /// An extended EventArgs class which contains changed profile state.
310     /// </summary>
311     public class ProfileStateEventArgs : EventArgs
312     {
313         private ProfileState _State = ProfileState.Disconnected;
314
315         internal ProfileStateEventArgs(ProfileState state)
316         {
317             _State = state;
318         }
319
320         /// <summary>
321         /// The profile state.
322         /// </summary>
323         public ProfileState State
324         {
325             get
326             {
327                 return _State;
328             }
329         }
330     }
331 }