[WiFi] Fix Dispose (#150)
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.WiFi / Tizen.Network.WiFi / WiFiAP.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.Threading.Tasks;
19 using System.Collections.Generic;
20 using Tizen.Applications;
21
22 namespace Tizen.Network.WiFi
23 {
24     /// <summary>
25     /// A class for managing the network information of the access point (AP).
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class WiFiAP : IDisposable
29     {
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;
38
39         private TizenSynchronizationContext context = new TizenSynchronizationContext();
40         private static TizenSynchronizationContext s_context = new TizenSynchronizationContext();
41
42         /// <summary>
43         /// The network information of the access point (AP).
44         /// </summary>
45         /// <since_tizen> 3 </since_tizen>
46         /// <value>The WiFiNetwork instance containing the network information of the AP.</value>
47         public WiFiNetwork NetworkInformation
48         {
49             get
50             {
51                 return _network;
52             }
53         }
54
55         /// <summary>
56         /// The security information of the access point (AP).
57         /// </summary>
58         /// <since_tizen> 3 </since_tizen>
59         /// <value>The WiFiSecurity instance containing security information of the AP.</value>
60         public WiFiSecurity SecurityInformation
61         {
62             get
63             {
64                 return _security;
65             }
66         }
67
68         internal WiFiAP(IntPtr handle)
69         {
70             Log.Debug(Globals.LogTag, "New WiFiAP. Handle: " + handle);
71             _apHandle = handle;
72             Initialize();
73         }
74
75         /// <summary>
76         /// Creates an object for the access point.
77         /// </summary>
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)
89         {
90             Log.Debug(Globals.LogTag, "New WiFiAP. Essid: " + essid);
91             createHandle(essid, true);
92             Initialize();
93         }
94
95         /// <summary>
96         /// Creates an object for the hidden access point.
97         /// </summary>
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)
110         {
111             createHandle(essid, hidden);
112             Initialize();
113         }
114
115         /// <summary>
116         /// Destroy the WiFiAP object
117         /// </summary>
118         ~WiFiAP()
119         {
120             Dispose(false);
121         }
122
123         /// <summary>
124         /// A method to destroy the managed WiFiAP objects.
125         /// </summary>
126         /// <since_tizen> 3 </since_tizen>
127         public void Dispose()
128         {
129             Dispose(true);
130             GC.SuppressFinalize(this);
131         }
132
133         private void Dispose(bool disposing)
134         {
135             if (_disposed)
136                 return;
137
138             Interop.WiFi.AP.Destroy(_apHandle);
139             _apHandle = IntPtr.Zero;
140             _disposed = true;
141         }
142
143         private void createHandle(string id, bool hidden)
144         {
145             int ret = -1;
146             if (id == null)
147             {
148                 throw new ArgumentNullException("Essid is null");
149             }
150
151             if (hidden)
152             {
153                 ret = Interop.WiFi.AP.CreateHiddenAP(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
154             }
155
156             else
157             {
158                 ret = Interop.WiFi.AP.Create(WiFiManagerImpl.Instance.GetSafeHandle(), id, out _apHandle);
159             }
160
161             if (ret != (int)WiFiError.None)
162             {
163                 Log.Error(Globals.LogTag, "Failed to create handle, Error - " + (WiFiError)ret);
164                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
165             }
166         }
167
168         private void Initialize()
169         {
170             Interop.WiFi.SafeWiFiAPHandle apHandle = new Interop.WiFi.SafeWiFiAPHandle(_apHandle);
171             _network = new WiFiNetwork(apHandle);
172             _security = new WiFiSecurity(apHandle);
173         }
174
175         /// <summary>
176         /// Refreshes the access point information.
177         /// </summary>
178         /// <since_tizen> 3 </since_tizen>
179         /// <feature>http://tizen.org/feature/network.wifi</feature>
180         /// <privilege>http://tizen.org/privilege/network.get</privilege>
181         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
182         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
183         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
184         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
185         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
186         public void Refresh()
187         {
188             Log.Debug(Globals.LogTag, "Refresh");
189             if (_disposed)
190             {
191                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
192             }
193             int ret = Interop.WiFi.AP.Refresh(_apHandle);
194             if (ret != (int)WiFiError.None)
195             {
196                 Log.Error(Globals.LogTag, "Failed to refresh ap handle, Error - " + (WiFiError)ret);
197                 WiFiErrorFactory.ThrowWiFiException(ret, _apHandle, "http://tizen.org/privilege/network.get");
198             }
199         }
200
201         /// <summary>
202         /// Connects the access point asynchronously.
203         /// </summary>
204         /// <since_tizen> 3 </since_tizen>
205         /// <returns> A task indicating whether the connect method is done or not.</returns>
206         /// <feature>http://tizen.org/feature/network.wifi</feature>
207         /// <privilege>http://tizen.org/privilege/network.set</privilege>
208         /// <privilege>http://tizen.org/privilege/network.get</privilege>
209         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
210         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
211         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
212         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
213         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
214         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
215         public Task ConnectAsync()
216         {
217             Log.Info(Globals.LogTag, "ConnectAsync");
218             if (_disposed)
219             {
220                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
221             }
222             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
223             IntPtr id;
224             lock (_callback_map)
225             {
226                 id = (IntPtr)_requestId++;
227                 _callback_map[id] = (error, key) =>
228                 {
229                     Log.Info(Globals.LogTag, "ConnectAsync done " + (WiFiError)error);
230                     if (error != (int)WiFiError.None)
231                     {
232                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
233                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
234                     }
235                     else
236                     {
237                         task.SetResult(true);
238                     }
239                     lock (_callback_map)
240                     {
241                         _callback_map.Remove(key);
242                     }
243                 };
244             }
245
246             context.Post((x) =>
247             {
248                 Log.Info(Globals.LogTag, "Interop.WiFi.Connect");
249                 int ret = Interop.WiFi.Connect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
250                 if (ret != (int)WiFiError.None)
251                 {
252                     Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
253                     WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
254                 }
255             }, null);
256
257             return task.Task;
258         }
259
260         /// <summary>
261         /// Connects the access point with the WPS asynchronously.
262         /// </summary>
263         /// <since_tizen> 3 </since_tizen>
264         /// <param name="info">A WpsInfo instance which is type of WpsPbcInfo or WpsPinInfo.</param>
265         /// <returns>A task indicating whether the ConnectWps method is done or not.</returns>
266         /// <feature>http://tizen.org/feature/network.wifi</feature>
267         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
268         /// <privilege>http://tizen.org/privilege/network.get</privilege>
269         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
270         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
271         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
272         /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
273         /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is an empty string or more than 7 characters.</exception>
274         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
275         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
276         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
277         public Task ConnectWpsAsync(WpsInfo info)
278         {
279             Log.Info(Globals.LogTag, "ConnectWpsAsync");
280             if (_disposed)
281             {
282                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
283             }
284             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
285             IntPtr id;
286             lock (_callback_map)
287             {
288                 id = (IntPtr)_requestId++;
289                 _callback_map[id] = (error, key) =>
290                 {
291                     Log.Info(Globals.LogTag, "ConnectWpsAsync done");
292                     if (error != (int)WiFiError.None)
293                     {
294                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
295                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
296                     }
297                     else
298                     {
299                         task.SetResult(true);
300                     }
301                     lock (_callback_map)
302                     {
303                         _callback_map.Remove(key);
304                     }
305                 };
306             }
307
308             context.Post((x) =>
309             {
310                 int ret = -1;
311                 if (info.GetType() == typeof(WpsPbcInfo))
312                 {
313                     Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPb");
314                     ret = Interop.WiFi.ConnectByWpsPbc(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
315                 }
316                 else if (info.GetType() == typeof(WpsPinInfo))
317                 {
318                     WpsPinInfo pinInfo = (WpsPinInfo)info;
319                     if (pinInfo.GetWpsPin() == null)
320                     {
321                         throw new ArgumentNullException("Wps pin should not be null");
322                     }
323
324                     if (pinInfo.GetWpsPin().Length == 0 || pinInfo.GetWpsPin().Length > 8)
325                     {
326                         throw new ArgumentOutOfRangeException("Wps pin should not be empty or more than 7 characters");
327                     }
328
329                     Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPin");
330                     ret = Interop.WiFi.ConnectByWpsPin(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, pinInfo.GetWpsPin(), _callback_map[id], id);
331                 }
332
333                 if (ret != (int)WiFiError.None)
334                 {
335                     Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
336                     WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
337                 }
338             }, null);
339
340             return task.Task;
341         }
342
343         /// <summary>
344         /// Connects the access point with WPS without SSID asynchronously.
345         /// </summary>
346         /// <since_tizen> 3 </since_tizen>
347         /// <param name="info">A WpsInfo instance which is of type WpsPbcInfo or WpsPinInfo.</param>
348         /// <returns>A task which contains Connected access point information.</returns>
349         /// <remarks>
350         /// If WpsPinInfo is used, its object has to be constructed with a pin which must be 4 or 8 characters long.
351         /// </remarks>
352         /// <feature>http://tizen.org/feature/network.wifi</feature>
353         /// <privilege>http://tizen.org/privilege/network.set</privilege>
354         /// <privilege>http://tizen.org/privilege/network.get</privilege>
355         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
356         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
357         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
358         /// <exception cref="ArgumentNullException">Thrown when the WpsPinInfo object is constructed with a null pin.</exception>
359         /// <exception cref="ArgumentOutOfRangeException">Thrown when the WpsPinInfo object is constructed with a pin which is not of 4 or 8 characters long.</exception>
360         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
361         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
362         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
363         public static Task<WiFiAP> ConnectWpsWithoutSsidAsync(WpsInfo info)
364         {
365             Log.Info(Globals.LogTag, "ConnectWpsWithoutSsidAsync");
366             TaskCompletionSource<WiFiAP> task = new TaskCompletionSource<WiFiAP>();
367             IntPtr id;
368             lock (s_callbackMap)
369             {
370                 id = (IntPtr)s_requestId++;
371                 s_callbackMap[id] = (error, key) =>
372                 {
373                     Log.Info(Globals.LogTag, "ConnectWpsWithoutSsidAsync done");
374                     if (error != (int)WiFiError.None)
375                     {
376                         Log.Error(Globals.LogTag, "Error occurs during WiFi connecting, " + (WiFiError)error);
377                         task.SetException(new InvalidOperationException("Error occurs during WiFi connecting, " + (WiFiError)error));
378                     }
379                     else
380                     {
381                         WiFiAP ap = WiFiManagerImpl.Instance.GetConnectedAP();
382                         task.SetResult(ap);
383                     }
384                     lock (s_callbackMap)
385                     {
386                         s_callbackMap.Remove(key);
387                     }
388                 };
389             }
390
391             s_context.Post((x) =>
392             {
393                 int ret = -1;
394                 if (info.GetType() == typeof(WpsPbcInfo))
395                 {
396                     Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPbcWithoutSsid");
397                     ret = Interop.WiFi.ConnectByWpsPbcWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), s_callbackMap[id], id);
398                 }
399                 else if (info.GetType() == typeof(WpsPinInfo))
400                 {
401                     WpsPinInfo pinInfo = (WpsPinInfo)info;
402                     if (pinInfo.GetWpsPin() == null)
403                     {
404                         throw new ArgumentNullException("Wps pin should not be null");
405                     }
406
407                     if (pinInfo.GetWpsPin().Length != 4 && pinInfo.GetWpsPin().Length != 8)
408                     {
409                         throw new ArgumentOutOfRangeException("Wps pin should be of 4 or 8 characters long");
410                     }
411
412                     Log.Info(Globals.LogTag, "Interop.WiFi.ConnectByWpsPinWithoutSsid");
413                     ret = Interop.WiFi.ConnectByWpsPinWithoutSsid(WiFiManagerImpl.Instance.GetSafeHandle(), pinInfo.GetWpsPin(), s_callbackMap[id], id);
414                 }
415
416                 if (ret != (int)WiFiError.None)
417                 {
418                     Log.Error(Globals.LogTag, "Failed to connect wifi, Error - " + (WiFiError)ret);
419                     WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle());
420                 }
421             }, null);
422
423             return task.Task;
424         }
425
426         /// <summary>
427         /// Disconnects the access point asynchronously.
428         /// </summary>
429         /// <since_tizen> 3 </since_tizen>
430         /// <returns> A task indicating whether the disconnect method is done or not.</returns>
431         /// <feature>http://tizen.org/feature/network.wifi</feature>
432         /// <privilege>http://tizen.org/privilege/network.set</privilege>
433         /// <privilege>http://tizen.org/privilege/network.get</privilege>
434         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
435         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
436         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
437         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
438         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
439         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
440         public Task DisconnectAsync()
441         {
442             Log.Debug(Globals.LogTag, "DisconnectAsync");
443             if (_disposed)
444             {
445                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
446             }
447             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
448             IntPtr id;
449             lock (_callback_map)
450             {
451                 id = (IntPtr)_requestId++;
452                 _callback_map[id] = (error, key) =>
453                 {
454                     Log.Info(Globals.LogTag, "DisconnectAsync done");
455                     if (error != (int)WiFiError.None)
456                     {
457                         Log.Error(Globals.LogTag, "Error occurs during WiFi disconnecting, " + (WiFiError)error);
458                         task.SetException(new InvalidOperationException("Error occurs during WiFi disconnecting, " + (WiFiError)error));
459                     }
460                     else
461                     {
462                         task.SetResult(true);
463                     }
464                     lock (_callback_map)
465                     {
466                         _callback_map.Remove(key);
467                     }
468                 };
469             }
470
471             context.Post((x) =>
472             {
473                 Log.Info(Globals.LogTag, "Interop.WiFi.Disconnect");
474                 int ret = Interop.WiFi.Disconnect(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle, _callback_map[id], id);
475                 if (ret != (int)WiFiError.None)
476                 {
477                     Log.Error(Globals.LogTag, "Failed to disconnect wifi, Error - " + (WiFiError)ret);
478                     WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
479                 }
480             }, null);
481
482             return task.Task;
483         }
484
485         /// <summary>
486         /// Deletes the information of a stored access point and disconnects it when the AP is connected.
487         /// 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.
488         /// </summary>
489         /// <since_tizen> 3 </since_tizen>
490         /// <feature>http://tizen.org/feature/network.wifi</feature>
491         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
492         /// <privilege>http://tizen.org/privilege/network.get</privilege>
493         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
494         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
495         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
496         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
497         /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
498         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
499         public void ForgetAP()
500         {
501             Log.Debug(Globals.LogTag, "ForgetAP");
502             if (_disposed)
503             {
504                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
505             }
506             int ret = Interop.WiFi.RemoveAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
507             if (ret != (int)WiFiError.None)
508             {
509                 Log.Error(Globals.LogTag, "Failed to forget AP, Error - " + (WiFiError)ret);
510                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
511             }
512         }
513
514         /// <summary>
515         /// Update the information of a stored access point.
516         /// When a AP information is changed, the change will not be applied until this method is called.
517         /// </summary>
518         /// <since_tizen> 5 </since_tizen>
519         /// <feature>http://tizen.org/feature/network.wifi</feature>
520         /// <privilege>http://tizen.org/privilege/network.profile</privilege>
521         /// <privilege>http://tizen.org/privilege/network.get</privilege>
522         /// <exception cref="NotSupportedException">Thrown when the Wi-Fi is not supported.</exception>
523         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
524         /// <exception cref="ObjectDisposedException">Thrown when the object instance is disposed or released.</exception>
525         /// <exception cref="OutOfMemoryException">Thrown when the system is out of memory.</exception>
526         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
527         public void Update()
528         {
529             Log.Debug(Globals.LogTag, "Update");
530             if (_disposed)
531             {
532                 throw new ObjectDisposedException("Invalid AP instance (Object may have been disposed or released)");
533             }
534             int ret = Interop.WiFi.UpdateAP(WiFiManagerImpl.Instance.GetSafeHandle(), _apHandle);
535             if (ret != (int)WiFiError.None)
536             {
537                 Log.Error(Globals.LogTag, "Failed to update AP, Error - " + (WiFiError)ret);
538                 WiFiErrorFactory.ThrowWiFiException(ret, WiFiManagerImpl.Instance.GetSafeHandle().DangerousGetHandle(), _apHandle);
539             }
540         }
541    }
542
543     /// <summary>
544     /// An abstract class which is used to represent the WPS information of the access point.
545     /// </summary>
546     /// <since_tizen> 3 </since_tizen>
547     public abstract class WpsInfo
548     {
549     }
550
551     /// <summary>
552     /// A class which is used to represent WPS PBC information of the access point.
553     /// </summary>
554     /// <since_tizen> 3 </since_tizen>
555     public class WpsPbcInfo : WpsInfo
556     {
557     }
558
559     /// <summary>
560     /// A class which is used to represent WPS PIN information of the access point.
561     /// </summary>
562     /// <since_tizen> 3 </since_tizen>
563     public class WpsPinInfo : WpsInfo
564     {
565         private string _pin;
566
567         private WpsPinInfo()
568         {
569         }
570
571         /// <summary>
572         /// A public constructor which instantiates WpsPinInfo class with the given pin.
573         /// </summary>
574         /// <since_tizen> 3 </since_tizen>
575         /// <param name="pin">WPS Pin of the access point.</param>
576         /// <remarks>
577         /// Pin should not be null or empty. It should be of less than 8 characters.
578         /// </remarks>
579         public WpsPinInfo(string pin)
580         {
581             _pin = pin;
582         }
583
584         internal string GetWpsPin()
585         {
586             return _pin;
587         }
588     }
589 }