Binding KeyboardGrab and KeyboardUnGrab
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Connection / Tizen.Network.Connection / ConnectionInternalManager.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.Threading.Tasks;
22 using System.Runtime.InteropServices;
23 using System.Collections;
24 using System.Threading;
25 using Tizen.Applications;
26
27 namespace Tizen.Network.Connection
28 {
29     class HandleHolder
30     {
31         private IntPtr Handle;
32         private int _tid;
33
34         public HandleHolder()
35         {
36             _tid = Thread.CurrentThread.ManagedThreadId;
37             Log.Info(Globals.LogTag, "PInvoke connection_create for Thread " + _tid);
38             int ret = Interop.Connection.Create(out Handle);
39             Log.Info(Globals.LogTag, "Handle: " + Handle);
40             if(ret != (int)ConnectionError.None)
41             {
42                 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");
43                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
44                 ConnectionErrorFactory.ThrowConnectionException(ret);
45             }
46         }
47
48         ~HandleHolder()
49         {
50             Destroy();
51         }
52
53         internal IntPtr GetHandle()
54         {
55             Log.Debug(Globals.LogTag, "handleholder handle = " + Handle);
56             return Handle;
57         }
58
59         private void Destroy()
60         {
61
62             Log.Info(Globals.LogTag, "PInvoke connection_destroy for Thread " + _tid);
63             Interop.Connection.Destroy(Handle);
64             if (Handle != IntPtr.Zero)
65             {
66                 Handle = IntPtr.Zero;
67             }
68         }
69     }
70
71     internal class ConnectionInternalManager
72     {
73         private static ConnectionInternalManager s_instance = null;
74         private static readonly object _lock = new object();
75
76         private EventHandler<ConnectionTypeEventArgs> _ConnectionTypeChanged = null;
77         private EventHandler<AddressEventArgs> _IPAddressChanged = null;
78         private EventHandler<EthernetCableStateEventArgs> _EthernetCableStateChanged = null;
79         private EventHandler<AddressEventArgs> _ProxyAddressChanged = null;
80
81         private static readonly object _ConnectionTypeChangedLock = new object();
82         private static readonly object _IPAddressChangedLock = new object();
83         private static readonly object _EthernetCableStateChangedLock = new object();
84         private static readonly object _ProxyAddressChangedLock = new object();
85
86
87         private Interop.Connection.ConnectionAddressChangedCallback _connectionAddressChangedCallback;
88         private Interop.Connection.ConnectionTypeChangedCallback _connectionTypeChangedCallback;
89         private Interop.Connection.ConnectionAddressChangedCallback _proxyAddressChangedCallback;
90         private Interop.Connection.EthernetCableStateChangedCallback _ethernetCableStateChangedCallback;
91
92         private Dictionary<IntPtr, Interop.Connection.ConnectionCallback> _callback_map =
93             new Dictionary<IntPtr, Interop.Connection.ConnectionCallback>();
94         private int _requestId = 0;
95
96         internal static ConnectionInternalManager Instance
97         {
98             get
99             {
100                 lock (_lock)
101                 {
102                     if (s_instance == null)
103                     {
104                         s_instance = new ConnectionInternalManager();
105                     }
106                     Log.Info(Globals.LogTag, "ConnectionInternalManager.Instance");
107                     return s_instance;
108                 }
109             }
110         }
111
112         private HandleHolder _handleHolder;
113
114         private ConnectionInternalManager()
115         {
116             Log.Info(Globals.LogTag, "ConnectionInternalManager constructor");
117             _handleHolder = new HandleHolder();
118             Log.Info(Globals.LogTag, "Success to get handle");
119         }
120
121         ~ConnectionInternalManager()
122         {
123             UnregisterEvents();
124         }
125
126         internal IntPtr GetHandle()
127         {
128             return _handleHolder.GetHandle();
129         }
130
131         internal event EventHandler<ConnectionTypeEventArgs> ConnectionTypeChanged
132         {
133             add
134             {
135                 lock (_ConnectionTypeChangedLock)
136                 {
137                     if (_ConnectionTypeChanged == null)
138                     {
139                         try
140                         {
141                             ConnectionTypeChangedStart();
142                         }
143                         catch (Exception e)
144                         {
145                             Log.Error(Globals.LogTag, "Exception on adding ConnectionTypeChanged\n" + e.ToString());
146                             return;
147                         }
148                     }
149                     _ConnectionTypeChanged += value;
150                 }
151             }
152             remove
153             {
154                 lock (_ConnectionTypeChangedLock)
155                 {
156                     _ConnectionTypeChanged -= value;
157                     if (_ConnectionTypeChanged == null)
158                     {
159                         try
160                         {
161                             ConnectionTypeChangedStop();
162                         }
163                         catch (Exception e)
164                         {
165                             Log.Error(Globals.LogTag, "Exception on removing ConnectionTypeChanged\n" + e.ToString());
166                         }
167                     }
168                 }
169             }
170         }
171
172         private void ConnectionTypeChangedStart()
173         {
174             Log.Info(Globals.LogTag, "Register ConnectionTypeChanged");
175             _connectionTypeChangedCallback = (ConnectionType type, IntPtr user_data) =>
176             {
177                 if (_ConnectionTypeChanged != null)
178                 {
179                     _ConnectionTypeChanged(null, new ConnectionTypeEventArgs(type));
180                 }
181             };
182
183             int ret = Interop.Connection.SetTypeChangedCallback(GetHandle(), _connectionTypeChangedCallback, IntPtr.Zero);
184             if ((ConnectionError)ret != ConnectionError.None)
185             {
186                 Log.Error(Globals.LogTag, "It failed to register connection type changed callback, " + (ConnectionError)ret);
187                 ConnectionErrorFactory.ThrowConnectionException(ret);
188             }
189         }
190
191         private void ConnectionTypeChangedStop()
192         {
193             Log.Info(Globals.LogTag, "Unregister ConnectionTypeChanged");
194             int ret = Interop.Connection.UnsetTypeChangedCallback(GetHandle());
195             if ((ConnectionError)ret != ConnectionError.None)
196             {
197                 Log.Error(Globals.LogTag, "It failed to unregister connection type changed callback, " + (ConnectionError)ret);
198                 ConnectionErrorFactory.ThrowConnectionException(ret);
199             }
200         }
201
202         internal event EventHandler<EthernetCableStateEventArgs> EthernetCableStateChanged
203         {
204             add
205             {
206                 lock(_EthernetCableStateChangedLock)
207                 {
208                     if (_EthernetCableStateChanged == null)
209                     {
210                         try
211                         {
212                             EthernetCableStateChangedStart();
213                         }
214                         catch (Exception e)
215                         {
216                             Log.Error(Globals.LogTag, "Exception on adding EthernetCableStateChanged\n" + e.ToString());
217                             return;
218                         }
219                     }
220                     _EthernetCableStateChanged += value;
221                 }
222             }
223             remove
224             {
225                 lock(_EthernetCableStateChangedLock)
226                 {
227                     _EthernetCableStateChanged -= value;
228                     if (_EthernetCableStateChanged == null)
229                     {
230                         try
231                         {
232                             EthernetCableStateChangedStop();
233                         }
234                         catch (Exception e)
235                         {
236                             Log.Error(Globals.LogTag, "Exception on removing EthernetCableStateChanged\n" + e.ToString());
237                         }
238                     }
239                 }
240             }
241         }
242
243         private void EthernetCableStateChangedStart()
244         {
245             Log.Info(Globals.LogTag, "Register EthernetCableStateChanged");
246             _ethernetCableStateChangedCallback = (EthernetCableState state, IntPtr user_data) =>
247             {
248                 if (_EthernetCableStateChanged != null)
249                 {
250                     _EthernetCableStateChanged(null, new EthernetCableStateEventArgs(state));
251                 }
252             };
253             int ret = Interop.Connection.SetEthernetCableStateChagedCallback(GetHandle(),
254                     _ethernetCableStateChangedCallback, IntPtr.Zero);
255             if ((ConnectionError)ret != ConnectionError.None)
256             {
257                 Log.Error(Globals.LogTag,
258                         "It failed to register ethernet cable state changed callback, " +
259                         (ConnectionError)ret);
260                 ConnectionErrorFactory.ThrowConnectionException(ret);
261             }
262         }
263
264         private void EthernetCableStateChangedStop()
265         {
266             Log.Info(Globals.LogTag, "Unregister EthernetCableStateChanged");
267             int ret = Interop.Connection.UnsetEthernetCableStateChagedCallback(GetHandle());
268             if ((ConnectionError)ret != ConnectionError.None)
269             {
270                 Log.Error(Globals.LogTag,
271                         "It failed to unregister ethernet cable state changed callback, " + 
272                         (ConnectionError)ret);
273                 ConnectionErrorFactory.ThrowConnectionException(ret);
274             }
275         }
276
277         internal event EventHandler<AddressEventArgs> IPAddressChanged
278         {
279             add
280             {
281                 lock (_IPAddressChangedLock)
282                 {
283                     if (_IPAddressChanged == null)
284                     {
285                         try
286                         {
287                             IPAddressChangedStart();
288                         }
289                         catch (Exception e)
290                         {
291                             Log.Error(Globals.LogTag, "Exception on adding IPAddressChanged\n" + e.ToString());
292                             return;
293                         }
294                     }
295                     _IPAddressChanged += value;
296                 }
297             }
298
299             remove
300             {
301                 lock (_IPAddressChangedLock)
302                 {
303                     _IPAddressChanged -= value;
304                     if (_IPAddressChanged == null)
305                     {
306                         try
307                         {
308                             IPAddressChangedStop();
309                         }
310                         catch (Exception e)
311                         {
312                             Log.Error(Globals.LogTag, "Exception on removing IPAddressChanged\n" + e.ToString());
313                         }
314                     }
315                 }
316             }
317         }
318
319         private void IPAddressChangedStart()
320         {
321             Log.Info(Globals.LogTag, "Register IPAddressChanged");
322             _connectionAddressChangedCallback = (IntPtr IPv4, IntPtr IPv6, IntPtr UserData) =>
323             {
324                 if (_IPAddressChanged != null)
325                 {
326                     string ipv4 = Marshal.PtrToStringAnsi(IPv4);
327                     string ipv6 = Marshal.PtrToStringAnsi(IPv6);
328
329                     if ((string.IsNullOrEmpty(ipv4) == false) || (string.IsNullOrEmpty(ipv6) == false))
330                     {
331                         _IPAddressChanged(null, new AddressEventArgs(ipv4, ipv6));
332                     }
333                 }
334             };
335
336             int ret = Interop.Connection.SetIPAddressChangedCallback(GetHandle(), _connectionAddressChangedCallback, IntPtr.Zero);
337             if ((ConnectionError)ret != ConnectionError.None)
338             {
339                 Log.Error(Globals.LogTag, "It failed to register callback for changing IP address, " + (ConnectionError)ret);
340             }
341         }
342
343         private void IPAddressChangedStop()
344         {
345             Log.Info(Globals.LogTag, "Unregister IPAddressChanged");
346             int ret = Interop.Connection.UnsetIPAddressChangedCallback(GetHandle());
347             if ((ConnectionError)ret != ConnectionError.None)
348             {
349                 Log.Error(Globals.LogTag, "It failed to unregister callback for changing IP address, " + (ConnectionError)ret);
350             }
351         }
352
353         internal event EventHandler<AddressEventArgs> ProxyAddressChanged
354         {
355             add
356             {
357                 lock (_ProxyAddressChangedLock)
358                 {
359                     if (_ProxyAddressChanged == null)
360                     {
361                         try
362                         {
363                             ProxyAddressChangedStart();
364                         }
365                         catch (Exception e)
366                         {
367                             Log.Error(Globals.LogTag, "Exception on adding ProxyAddressChanged\n" + e.ToString());
368                             return;
369                         }
370                     }
371                     _ProxyAddressChanged += value;
372                 }
373             }
374             remove
375             {
376                 lock (_ProxyAddressChangedLock)
377                 {
378                     _ProxyAddressChanged -= value;
379                     if (_ProxyAddressChanged == null)
380                     {
381                         try
382                         {
383                             ProxyAddressChangedStop();
384                         }
385                         catch (Exception e)
386                         {
387                             Log.Error(Globals.LogTag, "Exception on removing ProxyAddressChanged\n" + e.ToString());
388                         }
389                     }
390                 }
391             }
392         }
393
394         private void ProxyAddressChangedStart()
395         {
396             Log.Info(Globals.LogTag, "Register ProxyAddressChanged");
397             _proxyAddressChangedCallback = (IntPtr IPv4, IntPtr IPv6, IntPtr UserData) =>
398             {
399                 if (_ProxyAddressChanged != null)
400                 {
401                     string ipv4 = Marshal.PtrToStringAnsi(IPv4);
402                     string ipv6 = Marshal.PtrToStringAnsi(IPv6);
403
404                     if ((string.IsNullOrEmpty(ipv4) == false) || (string.IsNullOrEmpty(ipv6) == false))
405                     {
406                         _ProxyAddressChanged(null, new AddressEventArgs(ipv4, ipv6));
407                     }
408                 }
409             };
410
411             int ret = Interop.Connection.SetProxyAddressChangedCallback(GetHandle(), _proxyAddressChangedCallback, IntPtr.Zero);
412             if ((ConnectionError)ret != ConnectionError.None)
413             {
414                 Log.Error(Globals.LogTag, "It failed to register callback for changing proxy address, " + (ConnectionError)ret);
415             }
416         }
417
418         private void ProxyAddressChangedStop()
419         {
420             Log.Info(Globals.LogTag, "Unregister ProxyAddressChanged");
421             int ret = Interop.Connection.UnsetProxyAddressChangedCallback(GetHandle());
422             if ((ConnectionError)ret != ConnectionError.None)
423             {
424                 Log.Error(Globals.LogTag, "It failed to unregister callback for changing proxy address, " + (ConnectionError)ret);
425             }
426         }
427
428         private void UnregisterEvents()
429         {
430             if (_ConnectionTypeChanged != null)
431             {
432                 ConnectionTypeChangedStop();
433             }
434             if (_IPAddressChanged != null)
435             {
436                 IPAddressChangedStop();
437             }
438             if (_EthernetCableStateChanged != null)
439             {
440                 EthernetCableStateChangedStop();
441             }
442             if (_ProxyAddressChanged != null)
443             {
444                 ProxyAddressChangedStop();
445             }
446         }
447
448         internal int GetProfileIterator(ProfileListType type, out IntPtr iterator)
449         {
450             return Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
451         }
452
453         internal bool HasNext(IntPtr iterator)
454         {
455             return Interop.Connection.HasNextProfileIterator(iterator);
456         }
457
458         internal int NextProfileIterator(IntPtr iterator, out IntPtr profileHandle)
459         {
460             return Interop.Connection.GetNextProfileIterator(iterator, out profileHandle);
461         }
462
463         internal int DestoryProfileIterator(IntPtr iterator)
464         {
465             return Interop.Connection.DestroyProfileIterator(iterator);
466         }
467
468         internal System.Net.IPAddress GetIPAddress(AddressFamily family)
469         {
470             Log.Info(Globals.LogTag, "GetIPAddress " + family);
471             IntPtr ip;
472             int ret = Interop.Connection.GetIPAddress(GetHandle(), (int)family, out ip);
473             if ((ConnectionError)ret != ConnectionError.None)
474             {
475                 Log.Error(Globals.LogTag, "It failed to get IP address, " + (ConnectionError)ret);
476                 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");
477                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
478                 ConnectionErrorFactory.ThrowConnectionException(ret);
479             }
480
481             string result = Marshal.PtrToStringAnsi(ip);
482             Interop.Libc.Free(ip);
483             Log.Info(Globals.LogTag, "IPAddress " + result + " (" + result.Length + ")");
484             if (result.Length == 0)
485             {
486                 if (family == AddressFamily.IPv4)
487                     return System.Net.IPAddress.Parse("0.0.0.0");
488                 else
489                     return System.Net.IPAddress.Parse("::");
490             }
491             return System.Net.IPAddress.Parse(result);
492         }
493
494         internal IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses(ConnectionType type)
495         {
496             Log.Debug(Globals.LogTag, "GetAllIPv6Addresses");
497             List<System.Net.IPAddress> ipList = new List<System.Net.IPAddress>();
498             Interop.Connection.IPv6AddressCallback callback = (IntPtr ipv6Address, IntPtr userData) =>
499             {
500                 if (ipv6Address != IntPtr.Zero)
501                 {
502                     string ipv6 = Marshal.PtrToStringAnsi(ipv6Address);
503                     if (ipv6.Length == 0)
504                         ipList.Add(System.Net.IPAddress.Parse("::"));
505                     else
506                         ipList.Add(System.Net.IPAddress.Parse(ipv6));
507                     return true;
508                 }
509                 return false;
510             };
511
512             int ret = Interop.Connection.GetAllIPv6Addresses(GetHandle(), (int)type, callback, IntPtr.Zero);
513             if (ret != (int)ConnectionError.None)
514             {
515                 Log.Error(Globals.LogTag, "Failed to get all IPv6 addresses, Error - " + (ConnectionError)ret);
516                 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");
517                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
518                 ConnectionErrorFactory.ThrowConnectionException(ret);
519             }
520
521             return ipList;
522         }
523
524         internal string GetProxy(AddressFamily family)
525         {
526             Log.Debug(Globals.LogTag, "GetProxy " + family);
527             IntPtr ip;
528             int ret = Interop.Connection.GetProxy(GetHandle(), (int)family, out ip);
529             if ((ConnectionError)ret != ConnectionError.None)
530             {
531                 Log.Error(Globals.LogTag, "It failed to get proxy, " + (ConnectionError)ret);
532                 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");
533                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
534                 ConnectionErrorFactory.ThrowConnectionException(ret);
535             }
536
537             string result = Marshal.PtrToStringAnsi(ip);
538             Interop.Libc.Free(ip);
539             return result;
540         }
541
542         internal string GetMacAddress(ConnectionType type)
543         {
544             Log.Info(Globals.LogTag, "GetMacAddress " + type);
545             IntPtr mac;
546             int ret = Interop.Connection.GetMacAddress(GetHandle(), (int)type, out mac);
547             if ((ConnectionError)ret != ConnectionError.None)
548             {
549                 Log.Error(Globals.LogTag, "It failed to get mac address, " + (ConnectionError)ret);
550                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
551                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
552                 ConnectionErrorFactory.ThrowConnectionException(ret);
553             }
554
555             string result = Marshal.PtrToStringAnsi(mac);
556             Interop.Libc.Free(mac);
557             return result;
558         }
559
560         internal long GetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
561         {
562             Log.Debug(Globals.LogTag, "GetStatistics " + connectionType + ", " + statisticsType);
563             long size;
564             int ret = Interop.Connection.GetStatistics(GetHandle(), (int)connectionType,
565                     (int)statisticsType, out size);
566             if ((ConnectionError)ret != ConnectionError.None)
567             {
568                 Log.Error(Globals.LogTag, "It failed to get statistics, " + (ConnectionError)ret);
569                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
570                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
571                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
572                 ConnectionErrorFactory.ThrowConnectionException(ret);
573             }
574             return size;
575         }
576
577         internal void ResetStatistics(ConnectionType connectionType, StatisticsType statisticsType)
578         {
579             Log.Debug(Globals.LogTag, "ResetStatistics " + connectionType + ", " + statisticsType);
580             int ret = Interop.Connection.ResetStatistics(GetHandle(), (int)connectionType,
581                     (int)statisticsType);
582             if ((ConnectionError)ret != ConnectionError.None)
583             {
584                 Log.Error(Globals.LogTag, "It failed to reset statistics, " + (ConnectionError)ret);
585                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
586                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
587                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
588                 ConnectionErrorFactory.ThrowConnectionException(ret);
589             }
590         }
591
592         internal void AddRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
593         {
594             if (interfaceName != null && address != null && gateway != null)
595             {
596                 Log.Debug(Globals.LogTag, "AddRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
597                 int ret = Interop.Connection.AddRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
598                 if ((ConnectionError)ret != ConnectionError.None)
599                 {
600                     Log.Error(Globals.LogTag, "It failed to add route to the routing table, " + (ConnectionError)ret);
601                     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");
602                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.route)");
603                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
604                     ConnectionErrorFactory.ThrowConnectionException(ret);
605                 }
606             }
607
608             else
609             {
610                 throw new ArgumentNullException("Arguments are null");
611             }
612         }
613
614         internal void RemoveRoute(AddressFamily family, string interfaceName, System.Net.IPAddress address, System.Net.IPAddress gateway)
615         {
616             if (interfaceName != null && address != null && gateway != null)
617             {
618                 Log.Debug(Globals.LogTag, "RemoveRoute " + family + ", " + interfaceName + ", " + address + ", " + gateway);
619                 int ret = Interop.Connection.RemoveRoute(GetHandle(), family, interfaceName, address.ToString(), gateway.ToString());
620                 if ((ConnectionError)ret != ConnectionError.None)
621                 {
622                     Log.Error(Globals.LogTag, "It failed to remove route from the routing table, " + (ConnectionError)ret);
623                     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");
624                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.route)");
625                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
626                     ConnectionErrorFactory.ThrowConnectionException(ret);
627                 }
628             }
629
630             else
631             {
632                 throw new ArgumentNullException("Arguments are null");
633             }
634         }
635
636         internal ConnectionType ConnectionType
637         {
638             get
639             {
640                 Log.Info(Globals.LogTag, "get ConnectionType");
641                 int type = 0;
642                 int ret = Interop.Connection.GetType(GetHandle(), out type);
643                 if ((ConnectionError)ret != ConnectionError.None)
644                 {
645                     Log.Error(Globals.LogTag, "It failed to get connection type, " + (ConnectionError)ret);
646                     ConnectionErrorFactory.ThrowConnectionException(ret);
647                 }
648                 return (ConnectionType)type;
649             }
650         }
651
652         internal CellularState CellularState
653         {
654             get
655             {
656                 Log.Info(Globals.LogTag, "get CellularState");
657                 int type = 0;
658                 int ret = Interop.Connection.GetCellularState(GetHandle(), out type);
659                 if ((ConnectionError)ret != ConnectionError.None)
660                 {
661                     Log.Error(Globals.LogTag, "It failed to get cellular state, " + (ConnectionError)ret);
662                     ConnectionErrorFactory.ThrowConnectionException(ret);
663                 }
664                 return (CellularState)type;
665             }
666         }
667
668         internal ConnectionState WiFiState
669         {
670             get
671             {
672                 Log.Info(Globals.LogTag, "get WiFiState");
673                 int type = 0;
674                 int ret = Interop.Connection.GetWiFiState(GetHandle(), out type);
675                 if ((ConnectionError)ret != ConnectionError.None)
676                 {
677                     Log.Error(Globals.LogTag, "It failed to get wifi state, " + (ConnectionError)ret);
678                     ConnectionErrorFactory.ThrowConnectionException(ret);
679                 }
680                 return (ConnectionState)type;
681             }
682         }
683
684         internal ConnectionState BluetoothState
685         {
686             get
687             {
688                 Log.Info(Globals.LogTag, "get BluetoothState");
689                 int type = 0;
690                 int ret = Interop.Connection.GetBtState(GetHandle(), out type);
691                 if ((ConnectionError)ret != ConnectionError.None)
692                 {
693                     Log.Error(Globals.LogTag, "It failed to get bluetooth state, " + (ConnectionError)ret);
694                     ConnectionErrorFactory.ThrowConnectionException(ret);
695                 }
696                 return (ConnectionState)type;
697             }
698         }
699
700         internal ConnectionState EthernetState
701         {
702             get
703             {
704                 Log.Info(Globals.LogTag, "get ConnectionType");
705                 int type = 0;
706                 int ret = Interop.Connection.GetEthernetState(GetHandle(), out type);
707                 if ((ConnectionError)ret != ConnectionError.None)
708                 {
709                     Log.Error(Globals.LogTag, "It failed to get ethernet state, " + (ConnectionError)ret);
710                     ConnectionErrorFactory.ThrowConnectionException(ret);
711                 }
712                 return (ConnectionState)type;
713             }
714         }
715
716         internal EthernetCableState EthernetCableState
717         {
718             get
719             {
720                 Log.Info(Globals.LogTag, "get EthernetCableState");
721                 int type = 0;
722                 int ret = Interop.Connection.GetEthernetCableState(GetHandle(), out type);
723                 if ((ConnectionError)ret != ConnectionError.None)
724                 {
725                     Log.Error(Globals.LogTag, "It failed to get ethernet cable state, " + (ConnectionError)ret);
726                     ConnectionErrorFactory.ThrowConnectionException(ret);
727                 }
728                 return (EthernetCableState)type;
729             }
730         }
731
732         internal IntPtr CreateCellularProfile(ConnectionProfileType type, string keyword)
733         {
734             Log.Debug(Globals.LogTag, "CreateCellularProfile, " + type + ", " + keyword);
735             if (keyword != null)
736             {
737                 IntPtr handle = IntPtr.Zero;
738                 int ret = Interop.ConnectionProfile.Create((int)type, keyword, out handle);
739                 if ((ConnectionError)ret != ConnectionError.None)
740                 {
741                     Log.Error(Globals.LogTag, "It failed to Create profile, " + (ConnectionError)ret);
742                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
743                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
744                     ConnectionErrorFactory.ThrowConnectionException(ret);
745                 }
746
747                 return handle;
748             }
749
750             else
751             {
752                 throw new ArgumentNullException("Keyword is null");
753             }
754         }
755
756         internal void AddCellularProfile(CellularProfile profile)
757         {
758
759             Log.Debug(Globals.LogTag, "AddCellularProfile");
760             if (profile != null)
761             {
762                 if (profile.Type == ConnectionProfileType.Cellular)
763                 {
764                     int ret = Interop.Connection.AddProfile(GetHandle(), profile.ProfileHandle);
765                     if ((ConnectionError)ret != ConnectionError.None)
766                     {
767                         Log.Error(Globals.LogTag, "Failed to add cellular profile, " + (ConnectionError)ret);
768                         ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
769                         ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.profile)");
770                         ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
771                         ConnectionErrorFactory.ThrowConnectionException(ret);
772                     }
773                 }
774
775                 else
776                 {
777                     throw new ArgumentException("Profile type is not cellular");
778                 }
779             }
780
781             else
782             {
783                 throw new ArgumentNullException("Profile is null");
784             }
785         }
786
787         internal void RemoveProfile(ConnectionProfile profile)
788         {
789             Log.Debug(Globals.LogTag, "RemoveProfile");
790             if (profile != null)
791             {
792                 int ret = Interop.Connection.RemoveProfile(GetHandle(), profile.ProfileHandle);
793                 if ((ConnectionError)ret != ConnectionError.None)
794                 {
795                     Log.Error(Globals.LogTag, "It failed to remove profile, " + (ConnectionError)ret);
796                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.telephony");
797                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
798                     ConnectionErrorFactory.ThrowConnectionException(ret);
799                 }
800             }
801
802             else
803             {
804                 throw new ArgumentNullException("Profile is null");
805             }
806         }
807
808         internal void UpdateProfile(ConnectionProfile profile)
809         {
810             Log.Info(Globals.LogTag, "UpdateProfile");
811             if (profile != null)
812             {
813                 int ret = Interop.Connection.UpdateProfile(GetHandle(), profile.ProfileHandle);
814                 if ((ConnectionError)ret != ConnectionError.None)
815                 {
816                     Log.Error(Globals.LogTag, "It failed to update profile, " + (ConnectionError)ret);
817                     ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.ethernet");
818                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
819                     ConnectionErrorFactory.ThrowConnectionException(ret);
820                 }
821             }
822
823             else
824             {
825                 throw new ArgumentNullException("Profile is null");
826             }
827         }
828
829         internal ConnectionProfile GetCurrentProfile()
830         {
831             Log.Info(Globals.LogTag, "GetCurrentProfile");
832             IntPtr ProfileHandle;
833             int ret = Interop.Connection.GetCurrentProfile(GetHandle(), out ProfileHandle);
834             if ((ConnectionError)ret != ConnectionError.None)
835             {
836                 if ((ConnectionError)ret == ConnectionError.NoConnection)
837                 {
838                     Log.Error(Globals.LogTag, "No connection " + (ConnectionError)ret);
839                     return null;
840                 }
841                 else if ((ConnectionError)ret == ConnectionError.InvalidParameter)
842                 {
843                     throw new InvalidOperationException("Invalid handle");
844                 }
845                 else
846                 {
847                     Log.Error(Globals.LogTag, "It failed to get current profile, " + (ConnectionError)ret);
848                     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");
849                     ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
850                     ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
851                     ConnectionErrorFactory.ThrowConnectionException(ret);
852                 }
853             }
854
855             ConnectionProfile Profile = new ConnectionProfile(ProfileHandle);
856             return Profile;
857         }
858
859         internal ConnectionProfile GetDefaultCellularProfile(CellularServiceType type)
860         {
861             Log.Debug(Globals.LogTag, "GetDefaultCellularProfile");
862             IntPtr ProfileHandle;
863             int ret = Interop.Connection.GetDefaultCellularServiceProfile(GetHandle(), (int)type, out ProfileHandle);
864             if ((ConnectionError)ret != ConnectionError.None)
865             {
866                 Log.Error(Globals.LogTag, "Error: " + ret);
867                 Log.Error(Globals.LogTag, "It failed to get default cellular profile, " + (ConnectionError)ret);
868                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
869                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
870                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
871                 ConnectionErrorFactory.ThrowConnectionException(ret);
872             }
873
874             CellularProfile Profile = new CellularProfile(ProfileHandle);
875             return Profile;
876         }
877
878         internal Task SetDefaultCellularProfile(CellularServiceType type, ConnectionProfile profile)
879         {
880             Log.Info(Globals.LogTag, "SetDefaultCellularProfile");
881             if (profile != null)
882             {
883                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
884                 IntPtr id;
885                 lock (_callback_map)
886                 {
887                     id = (IntPtr)_requestId++;
888                     _callback_map[id] = (error, key) =>
889                     {
890                         Log.Info(Globals.LogTag, "SetDefaultCellularProfile done " + profile.Name);
891                         if (error != ConnectionError.None)
892                         {
893                             Log.Error(Globals.LogTag, "Error occurs during set default cellular profile, " + error);
894                             task.SetException(new InvalidOperationException("Error occurs during set default cellular profile, " + error));
895                         }
896                         else
897                         {
898                             task.SetResult(true);
899                         }
900                         lock (_callback_map)
901                         {
902                             _callback_map.Remove(key);
903                         }
904                     };
905                 }
906
907                 Log.Info(Globals.LogTag, "Interop.Connection.SetDefaultCellularServiceProfileAsync " + profile.Name);
908                 try
909                 {
910                     int ret = Interop.Connection.SetDefaultCellularServiceProfileAsync(GetHandle(), (int)type, profile.ProfileHandle, _callback_map[id], id);
911
912                     if ((ConnectionError)ret != ConnectionError.None)
913                     {
914                         Log.Error(Globals.LogTag, "It failed to set default cellular profile, " + (ConnectionError)ret);
915                         ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony");
916                         ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
917                         ConnectionErrorFactory.ThrowConnectionException(ret);
918                     }
919                 } catch (Exception e)
920                 {
921                     Log.Error(Globals.LogTag, "Exception on SetDefaultCellularServiceProfileAsync\n" + e.ToString());
922                     task.SetException(e);
923                 }
924
925                 return task.Task;
926             }
927             else
928             {
929                 throw new ArgumentNullException("Profile is null");
930             }
931         }
932
933
934         internal Task<IEnumerable<ConnectionProfile>> GetProfileListAsync(ProfileListType type)
935         {
936             Log.Debug(Globals.LogTag, "GetProfileListAsync");
937             var task = new TaskCompletionSource<IEnumerable<ConnectionProfile>>();
938
939             List<ConnectionProfile> Result = new List<ConnectionProfile>();
940             IntPtr iterator;
941             int ret = Interop.Connection.GetProfileIterator(GetHandle(), (int)type, out iterator);
942             if ((ConnectionError)ret != ConnectionError.None)
943             {
944                 Log.Error(Globals.LogTag, "It failed to get profile iterator, " + (ConnectionError)ret);
945                 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");
946                 ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
947                 ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
948                 ConnectionErrorFactory.ThrowConnectionException(ret);
949             }
950
951             while (Interop.Connection.HasNextProfileIterator(iterator))
952             {
953                 IntPtr nextH;
954                 IntPtr profileH;
955                 Interop.Connection.GetNextProfileIterator(iterator, out nextH);
956                 Interop.ConnectionProfile.Clone(out profileH, nextH);
957
958                 int profileType;
959                 Interop.ConnectionProfile.GetType(profileH, out profileType);
960
961                 if ((ConnectionProfileType)profileType == ConnectionProfileType.WiFi)
962                 {
963                     WiFiProfile cur = new WiFiProfile(profileH);
964                     Result.Add(cur);
965                 }
966                 else if ((ConnectionProfileType)profileType == ConnectionProfileType.Cellular)
967                 {
968                     CellularProfile cur = new CellularProfile(profileH);
969                     Result.Add(cur);
970                 }
971                 else {
972                     ConnectionProfile cur = new ConnectionProfile(profileH);
973                     Result.Add(cur);
974                 }
975             }
976             Interop.Connection.DestroyProfileIterator(iterator);
977             task.SetResult(Result);
978             return task.Task;
979         }
980
981         internal Task OpenProfileAsync(ConnectionProfile profile)
982         {
983             Log.Info(Globals.LogTag, "OpenProfileAsync");
984             if (profile != null)
985             {
986                 Log.Debug(Globals.LogTag, "OpenProfileAsync " + profile.Name);
987                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
988                 IntPtr id;
989                 lock (_callback_map)
990                 {
991                     id = (IntPtr)_requestId++;
992                     _callback_map[id] = (error, key) =>
993                     {
994                         Log.Info(Globals.LogTag, "OpenProfileAsync done " + profile.Name);
995                         if (error != ConnectionError.None)
996                         {
997                             Log.Error(Globals.LogTag, "Error occurs during connecting profile, " + error);
998                             task.SetException(new InvalidOperationException("Error occurs during connecting profile, " + error));
999                         }
1000                         else
1001                         {
1002                             task.SetResult(true);
1003                         }
1004                         lock (_callback_map)
1005                         {
1006                             _callback_map.Remove(key);
1007                         }
1008                     };
1009                 }
1010
1011                 Log.Info(Globals.LogTag, "Interop.Connection.OpenProfile " + profile.Name);
1012                 try
1013                 {
1014                     int ret = Interop.Connection.OpenProfile(GetHandle(), profile.ProfileHandle, _callback_map[id], id);
1015                     if ((ConnectionError)ret != ConnectionError.None)
1016                     {
1017                         Log.Error(Globals.LogTag, "It failed to connect profile, " + (ConnectionError)ret);
1018                         ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
1019                         ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
1020                         ConnectionErrorFactory.ThrowConnectionException(ret);
1021                     }
1022                 }
1023                 catch (Exception e)
1024                 {
1025                     Log.Error(Globals.LogTag, "Exception on OpenProfile\n" + e.ToString());
1026                     task.SetException(e);
1027                 }
1028
1029                 return task.Task;
1030             }
1031
1032             else
1033             {
1034                 throw new ArgumentNullException("Profile is null");
1035             }
1036         }
1037
1038         internal Task CloseProfileAsync(ConnectionProfile profile)
1039         {
1040             Log.Info(Globals.LogTag, "CloseProfileAsync");
1041             if (profile != null)
1042             {
1043                 Log.Info(Globals.LogTag, "CloseProfileAsync " + profile.Name);
1044                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
1045                 IntPtr id;
1046                 lock (_callback_map)
1047                 {
1048                     id = (IntPtr)_requestId++;
1049                     _callback_map[id] = (error, key) =>
1050                     {
1051                         Log.Info(Globals.LogTag, "CloseProfileAsync done " + profile.Name);
1052                         if (error!= ConnectionError.None)
1053                         {
1054                             Log.Error(Globals.LogTag, "Error occurs during disconnecting profile, " + error);
1055                             task.SetException(new InvalidOperationException("Error occurs during disconnecting profile, " + error));
1056                         }
1057                         else
1058                         {
1059                             task.SetResult(true);
1060                         }
1061                         lock (_callback_map)
1062                         {
1063                             _callback_map.Remove(key);
1064                         }
1065                     };
1066                 }
1067
1068                 Log.Info(Globals.LogTag, "Interop.Connection.CloseProfile " + profile.Name);
1069                 try
1070                 {
1071                     int ret = Interop.Connection.CloseProfile(GetHandle(), profile.ProfileHandle, _callback_map[id], id);
1072                     if ((ConnectionError)ret != ConnectionError.None)
1073                     {
1074                         Log.Error(Globals.LogTag, "It failed to disconnect profile, " + (ConnectionError)ret);
1075                         ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth");
1076                         ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.set)");
1077                         ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero || profile.ProfileHandle == IntPtr.Zero), "Connection or Profile Handle may have been disposed or released");
1078                         ConnectionErrorFactory.ThrowConnectionException(ret);
1079                     }
1080                 }
1081                 catch (Exception e)
1082                 {
1083                     Log.Error(Globals.LogTag, "Exception on CloseProfile\n" + e.ToString());
1084                     task.SetException(e);
1085                 }
1086
1087                 return task.Task;
1088             }
1089
1090             else
1091             {
1092                 throw new ArgumentNullException("Profile is null");
1093             }
1094         }
1095     }
1096 }