Release 4.0.0-preview1-00220
[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
23 namespace Tizen.Network.WiFi
24 {
25     static internal class Globals
26     {
27         internal const string LogTag = "Tizen.Network.WiFi";
28     }
29
30     internal class HandleHolder
31     {
32         private SafeWiFiManagerHandle _handle;
33
34         internal HandleHolder()
35         {
36             _handle = WiFiManagerImpl.Instance.Initialize();
37             Log.Debug(Globals.LogTag, "Handle: " + _handle);
38         }
39
40         internal SafeWiFiManagerHandle GetSafeHandle()
41         {
42             Log.Debug(Globals.LogTag, "Handleholder safehandle = " + _handle);
43             return _handle;
44         }
45     }
46
47     internal partial class WiFiManagerImpl
48     {
49         private static WiFiManagerImpl _instance = null;
50         private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
51         private int _requestId = 0;
52         private string _macAddress;
53
54         internal string MacAddress
55         {
56             get
57             {
58                 if (String.IsNullOrEmpty(_macAddress))
59                 {
60                     string address;
61                     int ret = Interop.WiFi.GetMacAddress(GetSafeHandle(), out address);
62                     if (ret != (int)WiFiError.None)
63                     {
64                         Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiError)ret);
65                         _macAddress = "";
66                     }
67                     else
68                     {
69                         _macAddress = address;
70                     }
71                 }
72                 return _macAddress;
73             }
74         }
75
76         internal string InterfaceName
77         {
78             get
79             {
80                 string name;
81                 int ret = Interop.WiFi.GetNetworkInterfaceName(GetSafeHandle(), out name);
82                 if (ret != (int)WiFiError.None)
83                 {
84                     Log.Error(Globals.LogTag, "Failed to get interface name, Error - " + (WiFiError)ret);
85                     return "";
86                 }
87                 return name;
88             }
89         }
90
91         internal WiFiConnectionState ConnectionState
92         {
93             get
94             {
95                 int state;
96                 int ret = Interop.WiFi.GetConnectionState(GetSafeHandle(), out state);
97                 if (ret != (int)WiFiError.None)
98                 {
99                     Log.Error(Globals.LogTag, "Failed to get connection state, Error - " + (WiFiError)ret);
100                     return WiFiConnectionState.Failure;
101                 }
102                 return (WiFiConnectionState)state;
103             }
104         }
105
106         internal bool IsActive
107         {
108             get
109             {
110                 bool active;
111                 int ret = Interop.WiFi.IsActive(GetSafeHandle(), out active);
112                 if (ret != (int)WiFiError.None)
113                 {
114                     Log.Error(Globals.LogTag, "Failed to get isActive, Error - " + (WiFiError)ret);
115                 }
116                 return active;
117             }
118         }
119
120         internal static WiFiManagerImpl Instance
121         {
122             get
123             {
124                 if (_instance == null)
125                 {
126                     Log.Debug(Globals.LogTag, "Instance is null");
127                     _instance = new WiFiManagerImpl();
128                 }
129
130                 return _instance;
131             }
132         }
133
134         private static ThreadLocal<HandleHolder> s_threadName = new ThreadLocal<HandleHolder>(() =>
135         {
136             Log.Info(Globals.LogTag, "In threadlocal delegate");
137             return new HandleHolder();
138         });
139
140         private WiFiManagerImpl()
141         {
142         }
143
144         internal SafeWiFiManagerHandle GetSafeHandle()
145         {
146             return s_threadName.Value.GetSafeHandle();
147         }
148
149         internal SafeWiFiManagerHandle Initialize()
150         {
151             SafeWiFiManagerHandle handle;
152             int ret = Interop.WiFi.Initialize(out handle);
153             if (ret != (int)WiFiError.None)
154             {
155                 Log.Error(Globals.LogTag, "Failed to initialize wifi, Error - " + (WiFiError)ret);
156                 WiFiErrorFactory.ThrowWiFiException(ret, "http://tizen.org/privilege/network.get");
157             }
158             return handle;
159         }
160
161         internal IEnumerable<WiFiAP> GetFoundAPs()
162         {
163             Log.Debug(Globals.LogTag, "GetFoundAPs");
164             List<WiFiAP> apList = new List<WiFiAP>();
165             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
166             {
167                 if (apHandle != IntPtr.Zero)
168                 {
169                     IntPtr clonedHandle;
170                     Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
171                     WiFiAP apItem = new WiFiAP(clonedHandle);
172                     apList.Add(apItem);
173                     return true;
174                 }
175                 return false;
176             };
177
178             int ret = Interop.WiFi.GetForeachFoundAPs(GetSafeHandle(), callback, IntPtr.Zero);
179             if (ret != (int)WiFiError.None)
180             {
181                 Log.Error(Globals.LogTag, "Failed to get all APs, Error - " + (WiFiError)ret);
182                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
183             }
184
185             return apList;
186         }
187
188         internal IEnumerable<WiFiAP> GetFoundSpecificAPs()
189         {
190             Log.Debug(Globals.LogTag, "GetFoundSpecificAPs");
191             List<WiFiAP> apList = new List<WiFiAP>();
192             Interop.WiFi.HandleCallback callback = (IntPtr apHandle, IntPtr userData) =>
193             {
194                 if (apHandle != IntPtr.Zero)
195                 {
196                     IntPtr clonedHandle;
197                     Interop.WiFi.AP.Clone(out clonedHandle, apHandle);
198                     WiFiAP apItem = new WiFiAP(clonedHandle);
199                     apList.Add(apItem);
200                     return true;
201                 }
202                 return false;
203
204             };
205
206             int ret = Interop.WiFi.GetForeachFoundSpecificAPs(GetSafeHandle(), callback, IntPtr.Zero);
207             if (ret != (int)WiFiError.None)
208             {
209                 Log.Error(Globals.LogTag, "Failed to get specific APs, Error - " + (WiFiError)ret);
210                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
211             }
212
213             return apList;
214         }
215
216         internal IEnumerable<WiFiConfiguration> GetWiFiConfigurations()
217         {
218             Log.Debug(Globals.LogTag, "GetWiFiConfigurations");
219             List<WiFiConfiguration> configList = new List<WiFiConfiguration>();
220             Interop.WiFi.HandleCallback callback = (IntPtr configHandle, IntPtr userData) =>
221             {
222                 if (configHandle != IntPtr.Zero)
223                 {
224                     IntPtr clonedConfig;
225                     Interop.WiFi.Config.Clone(configHandle, out clonedConfig);
226                     WiFiConfiguration configItem = new WiFiConfiguration(clonedConfig);
227                     configList.Add(configItem);
228                     return true;
229                 }
230                 return false;
231             };
232
233             int ret = Interop.WiFi.Config.GetForeachConfiguration(GetSafeHandle(), callback, IntPtr.Zero);
234             if (ret != (int)WiFiError.None)
235             {
236                 Log.Error(Globals.LogTag, "Failed to get configurations, Error - " + (WiFiError)ret);
237                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
238             }
239
240             return configList;
241         }
242
243         internal void SaveWiFiNetworkConfiguration(WiFiConfiguration config)
244         {
245             Log.Debug(Globals.LogTag, "SaveWiFiNetworkConfiguration");
246             if (config == null)
247             {
248                 throw new ArgumentNullException("WiFi configuration is null");
249             }
250
251             IntPtr configHandle = config.GetHandle();
252             int ret = Interop.WiFi.Config.SaveConfiguration(GetSafeHandle(), configHandle);
253             if (ret != (int)WiFiError.None)
254             {
255                 Log.Error(Globals.LogTag, "Failed to save configuration, Error - " + (WiFiError)ret);
256                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.profile");
257             }
258         }
259
260         internal WiFiAP GetConnectedAP()
261         {
262             Log.Debug(Globals.LogTag, "GetConnectedAP");
263             IntPtr apHandle;
264             int ret = Interop.WiFi.GetConnectedAP(GetSafeHandle(), out apHandle);
265             if (ret != (int)WiFiError.None)
266             {
267                 Log.Error(Globals.LogTag, "Failed to connect with AP, Error - " + (WiFiError)ret);
268                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle(), "http://tizen.org/privilege/network.get");
269             }
270             WiFiAP ap = new WiFiAP(apHandle);
271             return ap;
272         }
273
274         internal Task ActivateAsync()
275         {
276             Log.Debug(Globals.LogTag, "ActivateAsync");
277             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
278             IntPtr id;
279             lock (_callback_map)
280             {
281                 id = (IntPtr)_requestId++;
282                 _callback_map[id] = (error, key) =>
283                 {
284                     Log.Debug(Globals.LogTag, "wifi activated");
285                     if (error != (int)WiFiError.None)
286                     {
287                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
288                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
289                     }
290                     else
291                     {
292                         task.SetResult(true);
293                     }
294                     lock (_callback_map)
295                     {
296                         _callback_map.Remove(key);
297                     }
298                 };
299             }
300             int ret = Interop.WiFi.Activate(GetSafeHandle(), _callback_map[id], id);
301             if (ret != (int)WiFiError.None)
302             {
303                 Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
304                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
305             }
306             return task.Task;
307         }
308
309         internal Task ActivateWithWiFiPickerTestedAsync()
310         {
311             Log.Debug(Globals.LogTag, "ActivateWithWiFiPickerTestedAsync");
312             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
313             IntPtr id;
314             lock (_callback_map)
315             {
316                 id = (IntPtr)_requestId++;
317                 _callback_map[id] = (error, key) =>
318                 {
319                     Log.Debug(Globals.LogTag, "Activation finished");
320                     if (error != (int)WiFiError.None)
321                     {
322                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
323                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
324                     }
325                     else
326                     {
327                         task.SetResult(true);
328                     }
329                     lock (_callback_map)
330                     {
331                         _callback_map.Remove(key);
332                     }
333                 };
334             }
335             int ret = Interop.WiFi.ActivateWithWiFiPickerTested(GetSafeHandle(), _callback_map[id], id);
336             if (ret != (int)WiFiError.None)
337             {
338                 Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
339                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
340             }
341             return task.Task;
342         }
343
344         internal Task DeactivateAsync()
345         {
346             Log.Debug(Globals.LogTag, "DeactivateAsync");
347             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
348             IntPtr id;
349             lock (_callback_map)
350             {
351                 id = (IntPtr)_requestId++;
352                 _callback_map[id] = (error, key) =>
353                 {
354                     Log.Debug(Globals.LogTag, "Deactivation finished");
355                     if (error != (int)WiFiError.None)
356                     {
357                         Log.Error(Globals.LogTag, "Error occurs during WiFi deactivating, " + (WiFiError)error);
358                         task.SetException(new InvalidOperationException("Error occurs during WiFi deactivating, " + (WiFiError)error));
359                     }
360                     else
361                     {
362                         task.SetResult(true);
363                     }
364                     lock (_callback_map)
365                     {
366                         _callback_map.Remove(key);
367                     }
368                 };
369             }
370             int ret = Interop.WiFi.Deactivate(GetSafeHandle(), _callback_map[id], id);
371             if (ret != (int)WiFiError.None)
372             {
373                 Log.Error(Globals.LogTag, "Failed to deactivate wifi, Error - " + (WiFiError)ret);
374                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
375             }
376             return task.Task;
377         }
378
379         internal Task ScanAsync()
380         {
381             Log.Debug(Globals.LogTag, "ScanAsync");
382             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
383             IntPtr id;
384             lock (_callback_map)
385             {
386                 id = (IntPtr)_requestId++;
387                 _callback_map[id] = (error, key) =>
388                 {
389                     Log.Debug(Globals.LogTag, "Scanning finished");
390                     if (error != (int)WiFiError.None)
391                     {
392                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
393                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
394                     }
395                     else
396                     {
397                         task.SetResult(true);
398                     }
399                     lock (_callback_map)
400                     {
401                         _callback_map.Remove(key);
402                     }
403                 };
404             }
405             int ret = Interop.WiFi.Scan(GetSafeHandle(), _callback_map[id], id);
406             if (ret != (int)WiFiError.None)
407             {
408                 Log.Error(Globals.LogTag, "Failed to scan all AP, Error - " + (WiFiError)ret);
409                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
410             }
411             return task.Task;
412         }
413
414         internal Task ScanSpecificAPAsync(string essid)
415         {
416             Log.Debug(Globals.LogTag, "ScanSpecificAPAsync " + essid);
417             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
418             IntPtr id;
419             lock (_callback_map)
420             {
421                 id = (IntPtr)_requestId++;
422                 _callback_map[id] = (error, key) =>
423                 {
424                     Log.Debug(Globals.LogTag, "Scanning with specific AP finished");
425                     if (error != (int)WiFiError.None)
426                     {
427                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
428                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
429                     }
430                     else
431                     {
432                         task.SetResult(true);
433                     }
434                     lock (_callback_map)
435                     {
436                         _callback_map.Remove(key);
437                     }
438                 };
439             }
440             int ret = Interop.WiFi.ScanSpecificAP(GetSafeHandle(), essid, _callback_map[id], id);
441             if (ret != (int)WiFiError.None)
442             {
443                 Log.Error(Globals.LogTag, "Failed to scan with specific AP, Error - " + (WiFiError)ret);
444                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
445             }
446             return task.Task;
447         }
448     }
449 }