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