Release 4.0.0-preview1-00051
[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                     task.SetResult(true);
291                     lock (_callback_map)
292                     {
293                         _callback_map.Remove(key);
294                     }
295                 };
296             }
297             int ret = Interop.WiFi.Activate(GetSafeHandle(), _callback_map[id], id);
298             if (ret != (int)WiFiError.None)
299             {
300                 Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
301                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
302             }
303             return task.Task;
304         }
305
306         internal Task ActivateWithWiFiPickerTestedAsync()
307         {
308             Log.Debug(Globals.LogTag, "ActivateWithWiFiPickerTestedAsync");
309             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
310             IntPtr id;
311             lock (_callback_map)
312             {
313                 id = (IntPtr)_requestId++;
314                 _callback_map[id] = (error, key) =>
315                 {
316                     Log.Debug(Globals.LogTag, "Activation finished");
317                     if (error != (int)WiFiError.None)
318                     {
319                         Log.Error(Globals.LogTag, "Error occurs during WiFi activating, " + (WiFiError)error);
320                         task.SetException(new InvalidOperationException("Error occurs during WiFi activating, " + (WiFiError)error));
321                     }
322                     task.SetResult(true);
323                     lock (_callback_map)
324                     {
325                         _callback_map.Remove(key);
326                     }
327                 };
328             }
329             int ret = Interop.WiFi.ActivateWithWiFiPickerTested(GetSafeHandle(), _callback_map[id], id);
330             if (ret != (int)WiFiError.None)
331             {
332                 Log.Error(Globals.LogTag, "Failed to activate wifi, Error - " + (WiFiError)ret);
333                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
334             }
335             return task.Task;
336         }
337
338         internal Task DeactivateAsync()
339         {
340             Log.Debug(Globals.LogTag, "DeactivateAsync");
341             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
342             IntPtr id;
343             lock (_callback_map)
344             {
345                 id = (IntPtr)_requestId++;
346                 _callback_map[id] = (error, key) =>
347                 {
348                     Log.Debug(Globals.LogTag, "Deactivation finished");
349                     if (error != (int)WiFiError.None)
350                     {
351                         Log.Error(Globals.LogTag, "Error occurs during WiFi deactivating, " + (WiFiError)error);
352                         task.SetException(new InvalidOperationException("Error occurs during WiFi deactivating, " + (WiFiError)error));
353                     }
354                     task.SetResult(true);
355                     lock (_callback_map)
356                     {
357                         _callback_map.Remove(key);
358                     }
359                 };
360             }
361             int ret = Interop.WiFi.Deactivate(GetSafeHandle(), _callback_map[id], id);
362             if (ret != (int)WiFiError.None)
363             {
364                 Log.Error(Globals.LogTag, "Failed to deactivate wifi, Error - " + (WiFiError)ret);
365                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
366             }
367             return task.Task;
368         }
369
370         internal Task ScanAsync()
371         {
372             Log.Debug(Globals.LogTag, "ScanAsync");
373             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
374             IntPtr id;
375             lock (_callback_map)
376             {
377                 id = (IntPtr)_requestId++;
378                 _callback_map[id] = (error, key) =>
379                 {
380                     Log.Debug(Globals.LogTag, "Scanning finished");
381                     if (error != (int)WiFiError.None)
382                     {
383                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
384                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
385                     }
386                     task.SetResult(true);
387                     lock (_callback_map)
388                     {
389                         _callback_map.Remove(key);
390                     }
391                 };
392             }
393             int ret = Interop.WiFi.Scan(GetSafeHandle(), _callback_map[id], id);
394             if (ret != (int)WiFiError.None)
395             {
396                 Log.Error(Globals.LogTag, "Failed to scan all AP, Error - " + (WiFiError)ret);
397                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
398             }
399             return task.Task;
400         }
401
402         internal Task ScanSpecificAPAsync(string essid)
403         {
404             Log.Debug(Globals.LogTag, "ScanSpecificAPAsync " + essid);
405             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
406             IntPtr id;
407             lock (_callback_map)
408             {
409                 id = (IntPtr)_requestId++;
410                 _callback_map[id] = (error, key) =>
411                 {
412                     Log.Debug(Globals.LogTag, "Scanning with specific AP finished");
413                     if (error != (int)WiFiError.None)
414                     {
415                         Log.Error(Globals.LogTag, "Error occurs during WiFi scanning, " + (WiFiError)error);
416                         task.SetException(new InvalidOperationException("Error occurs during WiFi scanning, " + (WiFiError)error));
417                     }
418                     task.SetResult(true);
419                     lock (_callback_map)
420                     {
421                         _callback_map.Remove(key);
422                     }
423                 };
424             }
425             int ret = Interop.WiFi.ScanSpecificAP(GetSafeHandle(), essid, _callback_map[id], id);
426             if (ret != (int)WiFiError.None)
427             {
428                 Log.Error(Globals.LogTag, "Failed to scan with specific AP, Error - " + (WiFiError)ret);
429                 WiFiErrorFactory.ThrowWiFiException(ret, GetSafeHandle().DangerousGetHandle());
430             }
431             return task.Task;
432         }
433     }
434 }