2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Threading.Tasks;
19 using System.Collections.Generic;
20 using Tizen.Applications;
22 namespace Tizen.Network.WiFi
25 /// A class for managing the network information of the access point (AP).
27 /// <since_tizen> 3 </since_tizen>
28 public class WiFiAP : IDisposable
30 private IntPtr _apHandle = IntPtr.Zero;
31 private Dictionary<IntPtr, Interop.WiFi.VoidCallback> _callback_map = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
32 private static Dictionary<IntPtr, Interop.WiFi.VoidCallback> s_callbackMap = new Dictionary<IntPtr, Interop.WiFi.VoidCallback>();
33 private int _requestId = 0;
34 private static int s_requestId = 0;
35 private WiFiNetwork _network;
36 private WiFiSecurity _security;
37 private bool _disposed = false;
39 private TizenSynchronizationContext context = new TizenSynchronizationContext();
40 private static TizenSynchronizationContext s_context = new TizenSynchronizationContext();
43 /// The network information of the access point (AP).
45 /// <since_tizen> 3 </since_tizen>
46 /// <value>The WiFiNetwork instance containing the network information of the AP.</value>
47 public WiFiNetwork NetworkInformation
56 /// The security information of the access point (AP).
58 /// <since_tizen> 3 </since_tizen>
59 /// <value>The WiFiSecurity instance containing security information of the AP.</value>
60 public WiFiSecurity SecurityInformation
68 internal WiFiAP(IntPtr handle)
70 Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
76 /// Creates an object for the access point.
78 /// <since_tizen> 3 </since_tizen>
79 /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
80 /// <feature>http://tizen.org/feature/network.wifi</feature>
81 /// <privilege>http://tizen.org/privilege/network.get</privilege>
82 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
83 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
84 /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
85 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
86 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
87 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
88 public WiFiAP(string essid)
90 Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
91 createHandle(essid, true);
96 /// Creates an object for the hidden access point.
98 /// <since_tizen> 3 </since_tizen>
99 /// <param name="essid">The Extended Service Set Identifier of the access point.</param>
100 /// <param name="hidden">The value to set a hidden AP.</param>
101 /// <feature>http://tizen.org/feature/network.wifi</feature>
102 /// <privilege>http://tizen.org/privilege/network.get</privilege>
103 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
104 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
105 /// <exception cref="ArgumentNullException">Thrown when the ESSID is passed as null.</exception>
106 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
107 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
108 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
109 public WiFiAP(string essid, bool hidden)
111 createHandle(essid, hidden);
116 /// Destroy the WiFiAP object
124 /// A method to destroy the managed WiFiAP objects.
126 /// <since_tizen> 3 </since_tizen>
127 public void Dispose()
130 GC.SuppressFinalize(this);
133 private void Dispose(bool disposing)
140 Interop.WiFi.AP.Destroy(_apHandle);
141 _apHandle = IntPtr.Zero;
146 private void createHandle(string id, bool hidden)
151 throw new ArgumentNullException("Essid is null");
156 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
161 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
164 if (ret != (int)WiFiError.None)
166 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
167 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
171 private void Initialize()
173 Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
174 _network = new WiFiNetwork(apHandle);
175 _security = new WiFiSecurity(apHandle);
179 /// Refreshes the access point information.
181 /// <since_tizen> 3 </since_tizen>
182 /// <feature>http://tizen.org/feature/network.wifi</feature>
183 /// <privilege>http://tizen.org/privilege/network.get</privilege>
184 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
185 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
186 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
187 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
188 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
189 public void Refresh()
191 Log.Debug(Globals.LogTag, "Refresh");
194 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
196 int ret = Interop.WiFi.AP.Refresh(_apHandle);
197 if (ret != (int)WiFiError.None)
199 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
200 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
205 /// Connects the access point asynchronously.
207 /// <since_tizen> 3 </since_tizen>
208 /// <returns> A task indicating whether the connect method is done or not.</returns>
209 /// <feature>http://tizen.org/feature/network.wifi</feature>
210 /// <privilege>http://tizen.org/privilege/network.set</privilege>
211 /// <privilege>http://tizen.org/privilege/network.get</privilege>
212 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
213 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
214 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
215 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
216 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
217 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
218 public Task ConnectAsync()
220 Log.Info(Globals.LogTag, "ConnectAsync");
223 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
225 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
229 id = (IntPtr)_requestId++;
230 _callback_map[id] = (error, key) =>
232 Log.Info(Globals.LogTag, "ConnectAsync done " + (WiFiError)error);
233 if (error != (int)WiFiError.None)
235 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
236 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
240 task.SetResult(true);
244 _callback_map.Remove(key);
251 Log.Info(Globals.LogTag, "Interop.WiFi.Connect");
252 int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
253 if (ret != (int)WiFiError.None)
255 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
256 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
264 /// Connects the access point with the WPS asynchronously.
266 /// <since_tizen> 3 </since_tizen>
267 /// <param name="info">A WpsInfo instance which is type of WpsPbcInfo or WpsPinInfo.</param>
268 /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
269 /// <feature>http://tizen.org/feature/network.wifi</feature>
270 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
271 /// <privilege>http://tizen.org/privilege/network.get</privilege>
272 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
273 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
274 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
275 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
276 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is an empty string or more than 7 characters.</exception>
277 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
278 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
279 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
280 public Task ConnectWpsAsync(WpsInfo info)
282 Log.Info(Globals.LogTag, "ConnectWpsAsync");
285 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
287 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
291 id = (IntPtr)_requestId++;
292 _callback_map[id] = (error, key) =>
294 Log.Info(Globals.LogTag, "ConnectWpsAsync done");
295 if (error != (int)WiFiError.None)
297 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
298 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
302 task.SetResult(true);
306 _callback_map.Remove(key);
314 if (info.GetType() == typeof(WpsPbcInfo))
316 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPb");
317 ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
319 else if (info.GetType() == typeof(WpsPinInfo))
321 WpsPinInfo pinInfo = (WpsPinInfo)info;
322 if (pinInfo.GetWpsPin() == null)
324 throw new ArgumentNullException("Wps pin should not be null");
327 if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
329 throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
332 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPin");
333 ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
336 if (ret != (int)WiFiError.None)
338 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
339 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
347 /// Connects the access point with WPS without SSID asynchronously.
349 /// <since_tizen> 3 </since_tizen>
350 /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
351 /// <returns>A task which contains Connected access point information.</returns>
353 /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long.
355 /// <feature>http://tizen.org/feature/network.wifi</feature>
356 /// <privilege>http://tizen.org/privilege/network.set</privilege>
357 /// <privilege>http://tizen.org/privilege/network.get</privilege>
358 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
359 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
360 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
361 /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
362 /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is not of 4 or 8 characters long.</exception>
363 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
364 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
365 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
366 public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
368 Log.Info(Globals.LogTag, "ConnectWpsWithoutSsidAsync");
369 TaskCompletionSource<WiFiAP> task = new TaskCompletionSource<WiFiAP>();
373 id = (IntPtr)s_requestId++;
374 s_callbackMap[id] = (error, key) =>
376 Log.Info(Globals.LogTag, "ConnectWpsWithoutSsidAsync done");
377 if (error != (int)WiFiError.None)
379 Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
380 task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
384 WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
389 s_callbackMap.Remove(key);
394 s_context.Post((x) =>
397 if (info.GetType() == typeof(WpsPbcInfo))
399 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPbcWithoutSsid");
400 ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);
402 else if (info.GetType() == typeof(WpsPinInfo))
404 WpsPinInfo pinInfo = (WpsPinInfo)info;
405 if (pinInfo.GetWpsPin() == null)
407 throw new ArgumentNullException("Wps pin should not be null");
410 if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
412 throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
415 Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPinWithoutSsid");
416 ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
419 if (ret != (int)WiFiError.None)
421 Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
422 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
430 /// Disconnects the access point asynchronously.
432 /// <since_tizen> 3 </since_tizen>
433 /// <returns> A task indicating whether the disconnect method is done or not.</returns>
434 /// <feature>http://tizen.org/feature/network.wifi</feature>
435 /// <privilege>http://tizen.org/privilege/network.set</privilege>
436 /// <privilege>http://tizen.org/privilege/network.get</privilege>
437 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
438 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
439 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
440 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
441 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
442 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
443 public Task DisconnectAsync()
445 Log.Debug(Globals.LogTag, "DisconnectAsync");
448 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
450 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
454 id = (IntPtr)_requestId++;
455 _callback_map[id] = (error, key) =>
457 Log.Info(Globals.LogTag, "DisconnectAsync done");
458 if (error != (int)WiFiError.None)
460 Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
461 task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
465 task.SetResult(true);
469 _callback_map.Remove(key);
476 Log.Info(Globals.LogTag, "Interop.WiFi.Disconnect");
477 int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
478 if (ret != (int)WiFiError.None)
480 Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
481 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
489 /// Deletes the information of a stored access point and disconnects it when the AP is connected.
490 /// If an AP is connected, then the connection information will be stored. This information is used when a connection to that AP is established automatically.
492 /// <since_tizen> 3 </since_tizen>
493 /// <feature>http://tizen.org/feature/network.wifi</feature>
494 /// <privilege>http://tizen.org/privilege/network.profile</privilege>
495 /// <privilege>http://tizen.org/privilege/network.get</privilege>
496 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
497 /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
498 /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
499 /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
500 /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
501 /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
502 public void ForgetAP()
504 Log.Debug(Globals.LogTag, "ForgetAP");
507 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
509 int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
510 if (ret != (int)WiFiError.None)
512 Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
513 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
519 /// An abstract class which is used to represent the WPS information of the access point.
521 /// <since_tizen> 3 </since_tizen>
522 public abstract class WpsInfo
527 /// A class which is used to represent WPS PBC information of the access point.
529 /// <since_tizen> 3 </since_tizen>
530 public class WpsPbcInfo : WpsInfo
535 /// A class which is used to represent WPS PIN information of the access point.
537 /// <since_tizen> 3 </since_tizen>
538 public class WpsPinInfo : WpsInfo
547 /// A public constructor which instantiates WpsPinInfo class with the given pin.
549 /// <since_tizen> 3 </since_tizen>
550 /// <param name="pin">WPS Pin of the access point.</param>
552 /// Pin should not be null or empty. It should be of less than 8 characters.
554 public WpsPinInfo(string pin)
559 internal string GetWpsPin()