Release 9.0.0.16904
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Connection / Tizen.Network.Connection / ConnectionProfile.cs
1 /*
2  * Copyright (c) 2018 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 using Tizen.Applications;
23
24 namespace Tizen.Network.Connection
25 {
26     /// <summary>
27     /// This is the ConnectionProfile class. It provides event and properties of the connection profile.
28     /// </summary>
29     /// <since_tizen> 3 </since_tizen>
30     public class ConnectionProfile : IDisposable
31     {
32         internal IntPtr ProfileHandle = IntPtr.Zero;
33         private IAddressInformation IPv4;
34         private IAddressInformation IPv6;
35         private bool disposed = false;
36         private EventHandler<ProfileStateEventArgs> _ProfileStateChanged = null;
37
38         private Interop.ConnectionProfile.ProfileStateChangedCallback _profileChangedCallback;
39
40         internal IntPtr GetHandle()
41         {
42             return ProfileHandle;
43         }
44
45         /// <summary>
46         /// The event is called when the state of profile is changed.
47         /// </summary>
48         /// <since_tizen> 3 </since_tizen>
49         /// <feature>http://tizen.org/feature/network.ethernet</feature>
50         /// <feature>http://tizen.org/feature/network.telephony</feature>
51         /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
52         /// <feature>http://tizen.org/feature/network.wifi</feature>
53         /// <exception cref="System.NotSupportedException">Thrown when a feature is not supported.</exception>
54         public event EventHandler<ProfileStateEventArgs> ProfileStateChanged
55         {
56             add
57             {
58                 Log.Debug(Globals.LogTag, "ProfileStateChanged add");
59                 if (_ProfileStateChanged == null)
60                 {
61                     try
62                     {
63                         ProfileStateChangedStart();
64                     } catch (Exception e)
65                     {
66                         Log.Error(Globals.LogTag, "Exception on adding ProfileStateChanged\n" + e.ToString());
67                         return;
68                     }
69                 }
70                 _ProfileStateChanged += value;
71             }
72             remove
73             {
74                 Log.Debug(Globals.LogTag, "ProfileStateChanged remove");
75                 _ProfileStateChanged -= value;
76                 if (_ProfileStateChanged == null)
77                 {
78                     try
79                     {
80                         ProfileStateChangedStop();
81                     }
82                     catch (Exception e)
83                     {
84                         Log.Error(Globals.LogTag, "Exception on removing ProfileStateChanged\n" + e.ToString());
85                     }
86                 }
87             }
88         }
89
90         private void ProfileStateChangedStart()
91         {
92             _profileChangedCallback = (ProfileState state, IntPtr userData) =>
93             {
94                 if (_ProfileStateChanged != null)
95                 {
96                     _ProfileStateChanged(null, new ProfileStateEventArgs(state));
97                 }
98             };
99
100             Log.Debug(Globals.LogTag, "ProfileStateChangedStart");
101             int ret = Interop.ConnectionProfile.SetStateChangeCallback(ProfileHandle, _profileChangedCallback, IntPtr.Zero);
102             if ((ConnectionError)ret != ConnectionError.None)
103             {
104                 Log.Error(Globals.LogTag, "It failed to register callback for changing profile state, " + (ConnectionError)ret);
105                 ConnectionErrorFactory.ThrowConnectionException(ret);
106             }
107         }
108
109         private void ProfileStateChangedStop()
110         {
111             Log.Debug(Globals.LogTag, "ProfileStateChangedStop");
112             int ret = Interop.ConnectionProfile.UnsetStateChangeCallback(ProfileHandle);
113             if ((ConnectionError)ret != ConnectionError.None)
114             {
115                 Log.Error(Globals.LogTag, "It failed to unregister callback for changing profile state, " + (ConnectionError)ret);
116                 ConnectionErrorFactory.ThrowConnectionException(ret);
117             }
118         }
119
120         internal ConnectionProfile(IntPtr handle)
121         {
122             ProfileHandle = handle;
123             IPv4 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv4);
124             IPv6 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv6);
125         }
126
127         /// <summary>
128         /// Destroy the ConnectionProfile object
129         /// </summary>
130         ~ConnectionProfile()
131         {
132             Dispose(false);
133         }
134
135         /// <summary>
136         /// Disposes the memory allocated to unmanaged resources.
137         /// </summary>
138         /// <since_tizen> 3 </since_tizen>
139         public void Dispose()
140         {
141             Dispose(true);
142             GC.SuppressFinalize(this);
143         }
144
145         private void Dispose(bool disposing)
146         {
147             Log.Debug(Globals.LogTag, ">>> ConnectionProfile Dispose with " + disposing);
148             if (disposed)
149                 return;
150
151             // Free unmanaged objects
152             UnregisterEvents();
153             Destroy();
154             disposed = true;
155         }
156
157         private void UnregisterEvents()
158         {
159             if (_ProfileStateChanged != null)
160             {
161                 ProfileStateChangedStop();
162             }
163         }
164
165         private void Destroy()
166         {
167             int ret = Interop.ConnectionProfile.Destroy(ProfileHandle);
168             if ((ConnectionError)ret == ConnectionError.None)
169             {
170                 ProfileHandle = IntPtr.Zero;
171             }
172             
173         }
174
175         internal void CheckDisposed()
176         {
177             if (disposed)
178             {
179                 throw new ObjectDisposedException(GetType().FullName);
180             }
181         }
182
183         /// <summary>
184         /// The profile ID.
185         /// </summary>
186         /// <since_tizen> 3 </since_tizen>
187         /// <value>Unique ID of the profile.</value>
188         public string Id
189         {
190             get
191             {
192                 IntPtr Value;
193                 int ret = Interop.ConnectionProfile.GetId(ProfileHandle, out Value);
194                 if ((ConnectionError)ret != ConnectionError.None)
195                 {
196                     Log.Error(Globals.LogTag, "It failed to get id of connection profile, " + (ConnectionError)ret);
197                 }
198                 string result = Marshal.PtrToStringAnsi(Value);
199                 Interop.Libc.Free(Value);
200                 return result;
201             }
202         }
203
204         /// <summary>
205         /// The profile name.
206         /// </summary>
207         /// <since_tizen> 3 </since_tizen>
208         /// <value>User friendly name of the profile.</value>
209         public string Name
210         {
211             get
212             {
213                 IntPtr Value;
214                 int ret = Interop.ConnectionProfile.GetName(ProfileHandle, out Value);
215                 if ((ConnectionError)ret != ConnectionError.None)
216                 {
217                     Log.Error(Globals.LogTag, "It failed to get name of connection profile, " + (ConnectionError)ret);
218                 }
219                 string result = Marshal.PtrToStringAnsi(Value);
220                 Interop.Libc.Free(Value);
221                 return result;
222             }
223         }
224
225         /// <summary>
226         /// The network type.
227         /// </summary>
228         /// <since_tizen> 3 </since_tizen>
229         /// <value>Profile type of the network connection.</value>
230         public ConnectionProfileType Type
231         {
232             get
233             {
234                 int Value;
235                 int ret = Interop.ConnectionProfile.GetType(ProfileHandle, out Value);
236                 if ((ConnectionError)ret != ConnectionError.None)
237                 {
238                     Log.Error(Globals.LogTag, "It failed to get type of connection profile, " + (ConnectionError)ret);
239                 }
240                 return (ConnectionProfileType)Value;
241             }
242         }
243
244         /// <summary>
245         /// The name of the network interface.
246         /// </summary>
247         /// <since_tizen> 3 </since_tizen>
248         /// <value>Network interface name, for example, eth0 and pdp0.</value>
249         public string InterfaceName
250         {
251             get
252             {
253                 IntPtr Value;
254                 int ret = Interop.ConnectionProfile.GetNetworkInterfaceName(ProfileHandle, out Value);
255                 if ((ConnectionError)ret != ConnectionError.None)
256                 {
257                     Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
258                 }
259                 string result = Marshal.PtrToStringAnsi(Value);
260                 Interop.Libc.Free(Value);
261                 return result;
262             }
263         }
264
265         /// <summary>
266         /// Refreshes the profile information.
267         /// </summary>
268         /// <since_tizen> 3 </since_tizen>
269         /// <privilege>http://tizen.org/privilege/network.get</privilege>
270         /// <feature>http://tizen.org/feature/network.ethernet</feature>
271         /// <feature>http://tizen.org/feature/network.telephony</feature>
272         /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
273         /// <feature>http://tizen.org/feature/network.wifi</feature>
274         /// <exception cref="System.NotSupportedException">Thrown when a feature is not supported.</exception>
275         /// <exception cref="System.UnauthorizedAccessException">Thrown when a permission is denied.</exception>
276         /// <exception cref="System.InvalidOperationException">Thrown when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
277         /// <exception cref="System.ObjectDisposedException">Thrown when an operation is performed on a disposed object.</exception>
278         public void Refresh()
279         {
280             CheckDisposed();
281             int ret = Interop.ConnectionProfile.Refresh(ProfileHandle);
282             if ((ConnectionError)ret != ConnectionError.None)
283             {
284                 Log.Error(Globals.LogTag, "It failed to get network interface name, " + (ConnectionError)ret);
285                 if ((ConnectionError)ret == ConnectionError.InvalidParameter)
286                 {
287                     throw new InvalidOperationException("Invalid handle");
288                 }
289                 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");
290                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
291                 ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
292                 ConnectionErrorFactory.ThrowConnectionException(ret);
293             }
294         }
295
296         /// <summary>
297         /// Gets the network state.
298         /// </summary>
299         /// <since_tizen> 3 </since_tizen>
300         /// <param name="family">The address family.</param>
301         /// <returns>The network state.</returns>
302         /// <feature>http://tizen.org/feature/network.ethernet</feature>
303         /// <feature>http://tizen.org/feature/network.telephony</feature>
304         /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
305         /// <feature>http://tizen.org/feature/network.wifi</feature>
306         /// <exception cref="System.NotSupportedException">Thrown when a feature is not supported.</exception>
307         /// <exception cref="System.ArgumentException">Thrown when a value is an invalid parameter.</exception>
308         /// <exception cref="System.InvalidOperationException">Thrown when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
309         /// <exception cref="System.ObjectDisposedException">Thrown when an operation is performed on a disposed object.</exception>
310         public ProfileState GetState(AddressFamily family)
311         {
312             CheckDisposed();
313             int Value;
314             int ret = (int)ConnectionError.None;
315             if (family == AddressFamily.IPv4)
316             {
317                 ret = Interop.ConnectionProfile.GetState(ProfileHandle, out Value);
318             }
319
320             else
321             {
322                 ret = Interop.ConnectionProfile.GetIPv6State(ProfileHandle, out Value);
323             }
324
325             if ((ConnectionError)ret != ConnectionError.None)
326             {
327                 Log.Error(Globals.LogTag, "It failed to get profile state, " + (ConnectionError)ret);
328                 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");
329                 ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
330                 ConnectionErrorFactory.ThrowConnectionException(ret);
331             }
332
333             return (ProfileState)Value;
334         }
335
336         /// <summary>
337         /// The Proxy type.
338         /// </summary>
339         /// <since_tizen> 3 </since_tizen>
340         /// <value>Proxy type of the connection.</value>
341         /// <exception cref="System.NotSupportedException">Thrown during set when a feature is not supported.</exception>
342         /// <exception cref="System.ArgumentException">Thrown during set when a value is an invalid parameter.</exception>
343         /// <exception cref="System.InvalidOperationException">Thrown during set when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
344         /// <exception cref="System.ObjectDisposedException">Thrown during set when a operation is performed on a disposed object.</exception>
345         public ProxyType ProxyType
346         {
347             get
348             {
349                 int Value;
350                 int ret = Interop.ConnectionProfile.GetProxyType(ProfileHandle, out Value);
351                 if ((ConnectionError)ret != ConnectionError.None)
352                 {
353                     Log.Error(Globals.LogTag, "It failed to get proxy type, " + (ConnectionError)ret);
354                 }
355                 return (ProxyType)Value;
356
357             }
358
359             set
360             {
361                 CheckDisposed();
362                 int ret = Interop.ConnectionProfile.SetProxyType(ProfileHandle, (int)value);
363                 if ((ConnectionError)ret != ConnectionError.None)
364                 {
365                     Log.Error(Globals.LogTag, "It failed to set proxy type, " + (ConnectionError)ret);
366                     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");
367                     ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
368                     ConnectionErrorFactory.ThrowConnectionException(ret);
369                 }
370             }
371         }
372
373         /// <summary>
374         /// The proxy address.
375         /// </summary>
376         /// <since_tizen> 3 </since_tizen>
377         /// <value>Proxy address of the connection.</value>
378         /// <exception cref="System.NotSupportedException">Thrown during set when a feature is not supported.</exception>
379         /// <exception cref="System.ArgumentException">Thrown during set when a value is an invalid parameter.</exception>
380         /// <exception cref="System.ArgumentNullException">Thrown during set when a value is null.</exception>
381         /// <exception cref="System.InvalidOperationException">Thrown during set when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
382         /// <exception cref="System.ObjectDisposedException">Thrown when an operation is performed on a disposed object.</exception>
383         public string ProxyAddress
384         {
385             get
386             {
387                 IntPtr Value;
388                 int ret = Interop.ConnectionProfile.GetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, out Value);
389                 if ((ConnectionError)ret != ConnectionError.None)
390                 {
391                     Log.Error(Globals.LogTag, "It failed to get proxy address, " + (ConnectionError)ret);
392                 }
393                 string result = Marshal.PtrToStringAnsi(Value);
394                 Interop.Libc.Free(Value);
395                 return result;
396
397             }
398
399             set
400             {
401                 CheckDisposed();
402                 if (value != null)
403                 {
404                     int ret = Interop.ConnectionProfile.SetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, value);
405                     if ((ConnectionError)ret != ConnectionError.None)
406                     {
407                         Log.Error(Globals.LogTag, "It failed to set proxy address, " + (ConnectionError)ret);
408                         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");
409                         ConnectionErrorFactory.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
410                         ConnectionErrorFactory.ThrowConnectionException(ret);
411                     }
412                 }
413
414                 else
415                 {
416                     throw new ArgumentNullException("ProxyAddress is null");
417                 }
418             }
419         }
420
421         /// <summary>
422         /// The address information (IPv4).
423         /// </summary>
424         /// <since_tizen> 3 </since_tizen>
425         /// <value>Instance of IAddressInformation with IPV4 address.</value>
426         public IAddressInformation IPv4Settings
427         {
428             get
429             {
430                 return IPv4;
431
432             }
433         }
434
435         /// <summary>
436         /// The address information (IPv6).
437         /// </summary>
438         /// <since_tizen> 3 </since_tizen>
439         /// <value>Instance of IAddressInformation with IPV6 address.</value>
440         public IAddressInformation IPv6Settings
441         {
442             get
443             {
444                 return IPv6;
445             }
446         }
447     }
448
449     /// <summary>
450     /// An extended EventArgs class, which contains changed profile state.
451     /// </summary>
452     /// <since_tizen> 3 </since_tizen>
453     public class ProfileStateEventArgs : EventArgs
454     {
455         private ProfileState _State = ProfileState.Disconnected;
456
457         internal ProfileStateEventArgs(ProfileState state)
458         {
459             _State = state;
460         }
461
462         /// <summary>
463         /// The profile state.
464         /// </summary>
465         /// <since_tizen> 3 </since_tizen>
466         /// <value>State type of the connection profile.</value>
467         public ProfileState State
468         {
469             get
470             {
471                 return _State;
472             }
473         }
474     }
475 }