[WiFi][TCSACR-155] Remove ArgumentException descriptions (#323)
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.WiFi / Tizen.Network.WiFi / WiFiManagerImpl.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.Threading;
20 using System.Threading.Tasks;
21 using System.Runtime.InteropServices;
22 using Tizen.Applications;
23
24 namespace Tizen.Network.WiFi
25 {
26     static internal class Globals
27     {
28         internal const string LogTag = "Tizen.Network.WiFi";
29     }
30
31     internal class HandleHolder
32     {
33         private SafeWiFiManagerHandle _handle;
34
35         internal HandleHolder()
36         {
37             _handle = WiFiManagerImpl.Instance.Initialize();
38             Log.Info(Globals.LogTag, "Handle: " + _handle);
39         }
40
41         internal SafeWiFiManagerHandle GetSafeHandle()
42         {
43             Log.Debug(Globals.LogTag, "Handleholder safehandle = " + _handle);
44             return _handle;
45         }
46     }
47
48     internal partial class WiFiManagerImpl
49     {
50         private static readonly Lazy<WiFiManagerImpl> _instance =
51             new Lazy<WiFiManagerImpl>(() => new WiFiManagerImpl());
52
53         private TizenSynchronizationContext context = new TizenSynchronizationContext();
54         
55         private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map =
56             new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
57         
58         private int _requestId = 0;
59         private string _macAddress;
60
61         internal string MacAddress
62         {
63             get
64             {
65                 if (String.IsNullOrEmpty(_macAddress))
66                 {
67                     string address;
68                     int ret = Interop.WiFi.GetMacAddress(GetSafeHandle(), out address);
69                     if (ret != (int)WiFiError.None)
70                     {
71                         Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiError)ret);
72                         _macAddress = "";
73                     }
74                     else
75                     {
76                         _macAddress = address;
77                     }
78                 }
79                 return _macAddress;
80             }
81         }
82
83         internal string InterfaceName
84         {
85             get
86             {
87                 string name;
88                 int ret = Interop.WiFi.GetNetworkInterfaceName(GetSafeHandle(), out name);
89                 if (ret != (int)WiFiError.None)
90                 {
91                     Log.Error(Globals.LogTag, "Failed to get interface name, Error - " + (WiFiError)ret);
92                     return "";
93                 }
94                 return name;
95             }
96         }
97
98         internal WiFiConnectionState ConnectionState
99         {
100             get
101             {
102                 int state;
103                 int ret = Interop.WiFi.GetConnectionState(GetSafeHandle(), out state);
104                 if (ret != (int)WiFiError.None)
105                 {
106                     Log.Error(Globals.LogTag, "Failed to get connection state, Error - " + (WiFiError)ret);
107                     return WiFiConnectionState.Failure;
108                 }
109                 return (WiFiConnectionState)state;
110             }
111         }
112
113         internal bool IsActive
114         {
115             get
116             {
117                 bool active;
118                 int ret = Interop.WiFi.IsActive(GetSafeHandle(), out active);
119                 if (ret != (int)WiFiError.None)
120                 {
121                     Log.Error(Globals.LogTag, "Failed to get isActive, Error - " + (WiFiError)ret);
122                 }
123                 return active;
124             }
125         }
126
127         internal static WiFiManagerImpl Instance
128         {
129             get
130             {
131                return _instance.Value;
132             }
133         }
134
135         private static ThreadLocal<HandleHolder> s_threadName = new ThreadLocal<HandleHolder>(() =>
136         {
137             Log.Info(Globals.LogTag, "In threadlocal delegate");
138             return new HandleHolder();
139         });
140
141         private WiFiManagerImpl()
142         {
143             Log.Info(Globals.LogTag, "WiFiManagerImpl constructor");
144         }
145
146         internal SafeWiFiManagerHandle GetSafeHandle()
147         {
148             return s_threadName.Value.GetSafeHandle();
149         }
150
151         internal SafeWiFiManagerHandle Initialize()
152         {
153             SafeWiFiManagerHandle handle;
154             int tid = Thread.CurrentThread.ManagedThreadId;
155             Log.Info(Globals.LogTag, "PInvoke wifi_manager_initialize");
156             int ret = Interop.WiFi.Initialize(tid, out handle);
157             if (ret != (int)WiFiError.None)
158             {
159                 Log.Error(Globals.LogTag, "Failed to initialize wifi, Error - " + (WiFiError)ret);
160                 WiFiErrorFactory.ThrowWiFiException(ret, "http://tizen.org/privilege/network.get");
161             }
162             handle.SetTID(tid);
163             return handle;
164         }
165
166         internal IEnumerable<WiFiAP> GetFoundAPs()
167         {
168             Log.Info(Globals.LogTag, "GetFoundAPs");
169             List<WiFiAP> apList = new List<WiFiAP>();
170             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
171             {
172                 if (apHandle != IntPtr.Zero)
173                 {
174                     IntPtr clonedHandle;
175                     Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
176                     WiFiAP apItem = new WiFiAP(clonedHandle);
177                     apList.Add(apItem);
178                     return true;
179                 }
180                 return false;
181             };
182
183             int ret = Interop.WiFi.GetForeachFoundAPs(GetSafeHandle(), callback, IntPtr.Zero);
184             if (ret != (int)WiFiError.None)
185             {
186                 Log.Error(Globals.LogTag, "Failed to get all APs, Error - " + (WiFiError)ret);
187                 if (ret == (int)WiFiError.InvalidParameterError)
188                 {
189                     throw new InvalidOperationException("Invalid handle");
190                 }
191                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
192             }
193
194             return apList;
195         }
196
197         internal IEnumerable<WiFiAP> GetFoundSpecificAPs()
198         {
199             Log.Info(Globals.LogTag, "GetFoundSpecificAPs");
200             List<WiFiAP> apList = new List<WiFiAP>();
201             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
202             {
203                 if (apHandle != IntPtr.Zero)
204                 {
205                     IntPtr clonedHandle;
206                     Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
207                     WiFiAP apItem = new WiFiAP(clonedHandle);
208                     apList.Add(apItem);
209                     return true;
210                 }
211                 return false;
212
213             };
214
215             int ret = Interop.WiFi.GetForeachFoundSpecificAPs(GetSafeHandle(), callback, IntPtr.Zero);
216             if (ret != (int)WiFiError.None)
217             {
218                 Log.Error(Globals.LogTag, "Failed to get specific APs, Error - " + (WiFiError)ret);
219                 if (ret == (int)WiFiError.InvalidParameterError)
220                 {
221                     throw new InvalidOperationException("Invalid handle");
222                 }
223                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
224             }
225
226             return apList;
227         }
228
229         internal IEnumerable<WiFiAP> GetFoundBssids()
230         {
231             Log.Info(Globals.LogTag, "GetFoundBssids");
232             List<WiFiAP> apList = new List<WiFiAP>();
233             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
234             {
235                 if (apHandle != IntPtr.Zero)
236                 {
237                     IntPtr clonedHandle;
238                     Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
239                     WiFiAP apItem = new WiFiAP(clonedHandle);
240                     apList.Add(apItem);
241                     return true;
242                 }
243                 return false;
244             };
245
246             int ret = Interop.WiFi.GetForeachFoundBssids(GetSafeHandle(), callback, IntPtr.Zero);
247             if (ret != (int)WiFiError.None)
248             {
249                 Log.Error(Globals.LogTag, "Failed to get bssid APs, Error - " + (WiFiError)ret);
250                 if (ret == (int)WiFiError.InvalidParameterError)
251                 {
252                     throw new InvalidOperationException("Invalid handle");
253                 }
254                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
255             }
256
257             return apList;
258         }
259
260         internal IEnumerable<WiFiConfiguration> GetWiFiConfigurations()
261         {
262             Log.Debug(Globals.LogTag, "GetWiFiConfigurations");
263             List<WiFiConfiguration> configList = new List<WiFiConfiguration>();
264             Interop.WiFi.HandleCallback callback = (IntPtr configHandle, IntPtr userData) =>
265             {
266                 if (configHandle != IntPtr.Zero)
267                 {
268                     IntPtr clonedConfig;
269                     Interop.WiFi.Config.Clone(configHandle, out clonedConfig);
270                     WiFiConfiguration configItem = new WiFiConfiguration(clonedConfig);
271                     configList.Add(configItem);
272                     return true;
273                 }
274                 return false;
275             };
276
277             int ret = Interop.WiFi.Config.GetForeachConfiguration(GetSafeHandle(), callback, IntPtr.Zero);
278             if (ret != (int)WiFiError.None)
279             {
280                 Log.Error(Globals.LogTag, "Failed to get configurations, Error - " + (WiFiError)ret);
281                 if (ret == (int)WiFiError.InvalidParameterError)
282                 {
283                     throw new InvalidOperationException("Invalid handle");
284                 }
285                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
286             }
287
288             return configList;
289         }
290
291         internal void SaveWiFiNetworkConfiguration(WiFiConfiguration config)
292         {
293             Log.Debug(Globals.LogTag, "SaveWiFiNetworkConfiguration");
294             if (config == null)
295             {
296                 throw new ArgumentNullException("WiFi configuration is null");
297             }
298
299             IntPtr configHandle = config.GetHandle();
300             int ret = Interop.WiFi.Config.SaveConfiguration(GetSafeHandle(), configHandle);
301             if (ret != (int)WiFiError.None)
302             {
303                 Log.Error(Globals.LogTag, "Failed to save configuration, Error - " + (WiFiError)ret);
304                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
305             }
306         }
307
308         internal WiFiAP GetConnectedAP()
309         {
310             Log.Info(Globals.LogTag, "GetConnectedAP");
311             IntPtr apHandle;
312             int ret = Interop.WiFi.GetConnectedAP(GetSafeHandle(), out apHandle);
313             if (ret != (int)WiFiError.None)
314             {
315                 if (ret == (int)WiFiError.NoConnectionError)
316                 {
317                     Log.Error(Globals.LogTag, "No connection " + (WiFiError)ret);
318                     return null;
319                 }
320                 else if (ret == (int)WiFiError.InvalidParameterError)
321                 {
322                     throw new InvalidOperationException("Invalid handle");
323                 }
324                 else
325                 {
326                     Log.Error(Globals.LogTag, "Failed to get connected AP, Error - " + (WiFiError)ret);
327                     WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
328                 }
329             }
330             WiFiAP ap = new WiFiAP(apHandle);
331             return ap;
332         }
333
334         internal Task ActivateAsync()
335         {
336             Log.Info(Globals.LogTag, "ActivateAsync");
337             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
338             IntPtr id;
339             lock (_callback_map)
340             {
341                 id = (IntPtr)_requestId++;
342                 _callback_map[id] = (error, key) =>
343                 {
344                     Log.Info(Globals.LogTag, "ActivateAsync done");
345                     if (error != (int)WiFiError.None)
346                     {
347                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
348                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
349                     }
350                     else
351                     {
352                         task.SetResult(true);
353                     }
354                     lock (_callback_map)
355                     {
356                         _callback_map.Remove(key);
357                     }
358                 };
359             }
360
361             context.Post((x) =>
362             {
363                 Log.Info(Globals.LogTag, "Interop.WiFi.ActivateAsync");
364                 try
365                 {
366                     int ret = Interop.WiFi.Activate(GetSafeHandle(), _callback_map[id], id);
367                     if (ret != (int)WiFiError.None)
368                     {
369                         Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
370                         if (ret == (int)WiFiError.InvalidParameterError)
371                         {
372                             throw new InvalidOperationException("Invalid handle");
373                         }
374                         WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
375                     }
376                 }
377                 catch (Exception e)
378                 {
379                     Log.Error(Globals.LogTag, "Exception on ActivateAsync\n" + e.ToString());
380                     task.SetException(e);
381                 }
382             }, null);
383
384             return task.Task;
385         }
386
387         internal Task ActivateWithWiFiPickerTestedAsync()
388         {
389             Log.Info(Globals.LogTag, "ActivateWithWiFiPickerTestedAsync");
390             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
391             IntPtr id;
392             lock (_callback_map)
393             {
394                 id = (IntPtr)_requestId++;
395                 _callback_map[id] = (error, key) =>
396                 {
397                     Log.Info(Globals.LogTag, "ActivateWithWiFiPickerTestedAsync done");
398                     if (error != (int)WiFiError.None)
399                     {
400                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
401                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
402                     }
403                     else
404                     {
405                         task.SetResult(true);
406                     }
407                     lock (_callback_map)
408                     {
409                         _callback_map.Remove(key);
410                     }
411                 };
412             }
413
414             context.Post((x) =>
415             {
416                 Log.Info(Globals.LogTag, "Interop.WiFi.ActivateWithWiFiPickerTestedAsync");
417                 try
418                 {
419                     int ret = Interop.WiFi.ActivateWithWiFiPickerTested(GetSafeHandle(), _callback_map[id], id);
420                     if (ret != (int)WiFiError.None)
421                     {
422                         Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
423                         if (ret == (int)WiFiError.InvalidParameterError)
424                         {
425                             throw new InvalidOperationException("Invalid handle");
426                         }
427                         WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
428                     }
429                 }
430                 catch (Exception e)
431                 {
432                     Log.Error(Globals.LogTag, "Exception on ActivateWithWiFiPickerTestedAsync\n" + e.ToString());
433                     task.SetException(e);
434                 }
435             }, null);
436             
437             return task.Task;
438         }
439
440         internal Task DeactivateAsync()
441         {
442             Log.Info(Globals.LogTag, "DeactivateAsync");
443             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
444             IntPtr id;
445             lock (_callback_map)
446             {
447                 id = (IntPtr)_requestId++;
448                 _callback_map[id] = (error, key) =>
449                 {
450                     Log.Info(Globals.LogTag, "DeactivateAsync done");
451                     if (error != (int)WiFiError.None)
452                     {
453                         Log.Error(Globals.LogTag, "Error occurs during WiFi deactivating, " + (WiFiError)error);
454                         task.SetException(new InvalidOperationException("Error occurs during WiFi deactivating, " + (WiFiError)error));
455                     }
456                     else
457                     {
458                         task.SetResult(true);
459                     }
460                     lock (_callback_map)
461                     {
462                         _callback_map.Remove(key);
463                     }
464                 };
465             }
466
467             context.Post((x) =>
468             {
469                 Log.Info(Globals.LogTag, "Interop.WiFi.Deactivate");
470                 try
471                 {
472                     int ret = Interop.WiFi.Deactivate(GetSafeHandle(), _callback_map[id], id);
473                     if (ret != (int)WiFiError.None)
474                     {
475                         Log.Error(Globals.LogTag, "Failed to deactivate wifi, Error - " + (WiFiError)ret);
476                         if (ret == (int)WiFiError.InvalidParameterError)
477                         {
478                             throw new InvalidOperationException("Invalid handle");
479                         }
480                         WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
481                     }
482                 }
483                 catch (Exception e)
484                 {
485                     Log.Error(Globals.LogTag, "Exception on Deactivate\n" + e.ToString());
486                     task.SetException(e);
487                 }
488             }, null);
489
490             return task.Task;           
491         }
492
493         internal Task ScanAsync()
494         {
495             Log.Info(Globals.LogTag, "ScanAsync");
496             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
497             IntPtr id;
498             lock (_callback_map)
499             {
500                 id = (IntPtr)_requestId++;
501                 _callback_map[id] = (error, key) =>
502                 {
503                     Log.Info(Globals.LogTag, "ScanAsync done");
504                     if (error != (int)WiFiError.None)
505                     {
506                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
507                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
508                     }
509                     else
510                     {
511                         task.SetResult(true);
512                     }
513                     lock (_callback_map)
514                     {
515                         _callback_map.Remove(key);
516                     }
517                 };
518             }
519
520             context.Post((x) =>
521             {
522                 Log.Info(Globals.LogTag, "Interop.WiFi.Scan");
523                 try
524                 {
525                     int ret = Interop.WiFi.Scan(GetSafeHandle(), _callback_map[id], id);
526                     if (ret != (int)WiFiError.None)
527                     {
528                         Log.Error(Globals.LogTag, "Failed to scan all AP, Error - " + (WiFiError)ret);
529                         if (ret == (int)WiFiError.InvalidParameterError)
530                         {
531                             throw new InvalidOperationException("Invalid handle");
532                         }
533                         WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
534                     }
535                 }
536                 catch (Exception e)
537                 {
538                     Log.Error(Globals.LogTag, "Exception on Scan\n" + e.ToString());
539                     task.SetException(e);
540                 }
541             }, null);
542
543             return task.Task;
544         }
545
546         internal Task ScanSpecificAPAsync(string essid)
547         {
548             Log.Info(Globals.LogTag, "ScanSpecificAPAsync " + essid);
549             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
550             IntPtr id;
551             lock (_callback_map)
552             {
553                 id = (IntPtr)_requestId++;
554                 _callback_map[id] = (error, key) =>
555                 {
556                     Log.Info(Globals.LogTag, "ScanSpecificAPAsync Done " + essid);
557                     if (error != (int)WiFiError.None)
558                     {
559                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
560                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
561                     }
562                     else
563                     {
564                         task.SetResult(true);
565                     }
566                     lock (_callback_map)
567                     {
568                         _callback_map.Remove(key);
569                     }
570                 };
571             }
572
573             context.Post((x) =>
574             {
575                 Log.Info(Globals.LogTag, "Interop.WiFi.ScanSpecificAPAsync");
576                 try
577                 {
578                     int ret = Interop.WiFi.ScanSpecificAP(GetSafeHandle(), essid, _callback_map[id], id);
579                     if (ret != (int)WiFiError.None)
580                     {
581                         Log.Error(Globals.LogTag, "Failed to scan with specific AP, Error - " + (WiFiError)ret);
582                         WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
583                     }
584                 }
585                 catch (Exception e)
586                 {
587                     Log.Error(Globals.LogTag, "Exception on ScanSpecificAPAsync\n" + e.ToString());
588                     task.SetException(e);
589                 }
590             }, null);
591
592             return task.Task;
593         }
594
595         internal Task BssidScanAsync()
596         {
597             Log.Info(Globals.LogTag, "BssidScanAsync");
598             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
599             IntPtr id;
600             lock (_callback_map)
601             {
602                 id = (IntPtr)_requestId++;
603                 _callback_map[id] = (error, key) =>
604                 {
605                     Log.Info(Globals.LogTag, "BssidScanAsync done");
606                     if (error != (int)WiFiError.None)
607                     {
608                         Log.Error(Globals.LogTag, "Error occurs during bssid scanning, " + (WiFiError)error);
609                         task.SetException(new InvalidOperationException("Error occurs during bssid scanning, " + (WiFiError)error));
610                     }
611                     else
612                     {
613                         task.SetResult(true);
614                     }
615                     lock (_callback_map)
616                     {
617                         _callback_map.Remove(key);
618                     }
619                 };
620             }
621
622             context.Post((x) =>
623             {
624                 Log.Info(Globals.LogTag, "Interop.WiFi.BssidScan");
625                 try
626                 {
627                     int ret = Interop.WiFi.BssidScan(GetSafeHandle(), _callback_map[id], id);
628                     if (ret != (int)WiFiError.None)
629                     {
630                         Log.Error(Globals.LogTag, "Failed to scan Bssid AP, Error - " + (WiFiError)ret);
631                         if (ret == (int)WiFiError.InvalidParameterError)
632                         {
633                             throw new InvalidOperationException("Invalid handle");
634                         }
635                         WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
636                     }
637                 }
638                 catch (Exception e)
639                 {
640                     Log.Error(Globals.LogTag, "Exception on BssidScan\n" + e.ToString());
641                     task.SetException(e);
642                 }
643             }, null);
644
645             return task.Task;
646         }
647     }
648 }