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