[C# Wi-Fi Direct] Adding C# Wi-Fi Direct code
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.WiFiDirect / Tizen.Network.WiFiDirect / WiFiDirectManagerImpl.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.Runtime.InteropServices;
20 using System.Threading;
21
22 namespace Tizen.Network.WiFiDirect
23 {
24     internal class WiFiDirectThreadLocal
25     {
26         private int _threadId;
27         internal WiFiDirectThreadLocal(int id)
28         {
29             _threadId = id;
30         }
31
32         public int ThreadId
33         {
34             get
35             {
36                 return _threadId;
37             }
38         }
39
40         ~WiFiDirectThreadLocal()
41         {
42             Log.Info(Globals.LogTag, "Deinitializing Wi-Fi direct");
43             int ret = Interop.WiFiDirect.Deinitialize();
44             if (ret != (int)WiFiDirectError.None)
45             {
46                 Log.Error(Globals.LogTag, "Failed to deinitialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
47                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
48             }
49
50             else
51             {
52                 Globals.s_isInitialize = false;
53             }
54         }
55     }
56
57     internal static class Globals
58     {
59         internal const string LogTag = "Tizen.Network.WiFiDirect";
60         internal static bool s_isInitialize = false;
61         internal static bool s_isDisplay = false;
62         private static ThreadLocal<WiFiDirectThreadLocal> s_threadName = new ThreadLocal<WiFiDirectThreadLocal>(() =>
63         {
64             Log.Info(Globals.LogTag, "In threadlocal delegate");
65             return new WiFiDirectThreadLocal(Thread.CurrentThread.ManagedThreadId);
66         });
67         internal static bool IsActivated
68         {
69             get
70             {
71                 WiFiDirectState _state = WiFiDirectManager.State;
72                 if (IsInitialize)
73                 {
74                     if (_state == WiFiDirectState.Deactivated || _state == WiFiDirectState.Deactivating)
75                     {
76                         return false;
77                     }
78
79                     else
80                     {
81                         return true;
82                     }
83                 }
84
85                 else
86                 {
87                     return false;
88                 }
89             }
90         }
91
92         private static bool IsUniqueThread()
93         {
94             if (s_threadName.IsValueCreated)
95             {
96                 Log.Info(Globals.LogTag, "This thread is old");
97                 return false;
98             }
99
100             else
101             {
102                 WiFiDirectThreadLocal obj = s_threadName.Value;
103                 Log.Info(Globals.LogTag, "This thread is new , Id = " + obj.ThreadId);
104                 return true;
105             }
106         }
107
108         internal static bool IsInitialize
109         {
110             get
111             {
112                 if(Globals.IsUniqueThread() || !Globals.s_isInitialize)
113                 {
114                     WiFiDirectManagerImpl.Instance.Initialize();
115                 }
116
117                 return (Globals.s_isInitialize);
118             }
119         }
120     }
121
122     /// <summary>
123     /// Implementation of Wi-Fi Direct Apis
124     /// </summary>
125     internal partial class WiFiDirectManagerImpl : IDisposable
126     {
127         private event EventHandler<StateChangedEventArgs> _stateChanged;
128         private event EventHandler<DiscoveryStateChangedEventArgs > _discoveryStateChanged;
129         private event EventHandler<PeerFoundEventArgs > _peerFound;
130         private event EventHandler<DeviceStateChangedEventArgs > _deviceStateChanged;
131         private event EventHandler<ConnectionStatusChangedEventArgs > _connectionStatusChanged;
132
133         private Interop.WiFiDirect.StateChangedCallback _stateChangedCallback;
134         private Interop.WiFiDirect.DiscoveryStateChangedCallback _discoveryStateChangedCallback;
135         private Interop.WiFiDirect.PeerFoundCallback _peerFoundCallback;
136         private Interop.WiFiDirect.DeviceStateChangedCallback _deviceStateChangedCallback;
137         private Interop.WiFiDirect.ConnectionStateChangedCallback _connectionChangedCallback;
138
139         internal event EventHandler<StateChangedEventArgs> StateChanged
140         {
141             add
142             {
143                 if (_stateChanged == null)
144                 {
145                     RegisterStateChangedEvent();
146                 }
147
148                 _stateChanged += value;
149             }
150
151             remove
152             {
153                 _stateChanged -= value;
154                 if (_stateChanged == null)
155                 {
156                     UnregisterStateChangedEvent();
157                 }
158             }
159         }
160
161         internal event EventHandler<DiscoveryStateChangedEventArgs> DiscoveryStateChanged
162         {
163             add
164             {
165                 if (_discoveryStateChanged == null)
166                 {
167                     RegisterDiscoveryStateChangedEvent();
168                 }
169
170                 _discoveryStateChanged += value;
171             }
172
173             remove
174             {
175                 _discoveryStateChanged -= value;
176                 if (_discoveryStateChanged == null)
177                 {
178                     UnregisterDiscoveryStateChangedEvent();
179                 }
180             }
181         }
182
183         internal event EventHandler<PeerFoundEventArgs> PeerFound
184         {
185             add
186             {
187                 if (_peerFound == null)
188                 {
189                     RegisterPeerFoundEvent();
190                 }
191
192                 _peerFound += value;
193             }
194
195             remove
196             {
197                 _peerFound -= value;
198                 if (_peerFound == null)
199                 {
200                     UnregisterPeerFoundEvent();
201                 }
202             }
203         }
204
205         internal event EventHandler<DeviceStateChangedEventArgs> DeviceStateChanged
206         {
207             add
208             {
209                 if (_deviceStateChanged == null)
210                 {
211                     RegisterDeviceStateChangedEvent();
212                 }
213
214                 _deviceStateChanged += value;
215             }
216
217             remove
218             {
219                 _deviceStateChanged -= value;
220                 if (_deviceStateChanged == null)
221                 {
222                     UnregisterDeviceStateChangedEvent();
223                 }
224             }
225         }
226
227         internal event EventHandler<ConnectionStatusChangedEventArgs> ConnectionStatusChanged
228         {
229             add
230             {
231                 if (_connectionStatusChanged == null)
232                 {
233                     RegisterConnectionStatusChangedEvent();
234                 }
235
236                 _connectionStatusChanged += value;
237             }
238
239             remove
240             {
241                 _connectionStatusChanged -= value;
242                 if (_connectionStatusChanged == null)
243                 {
244                     UnregisterConnectionStatusChangedEvent();
245                 }
246             }
247         }
248
249         private bool _disposed = false;
250         private static WiFiDirectManagerImpl _instance;
251
252         private void RegisterStateChangedEvent()
253         {
254             _stateChangedCallback = (WiFiDirectState stateInfo, IntPtr userData) =>
255             {
256                 if (_stateChanged != null)
257                 {
258                     WiFiDirectState state = stateInfo;
259                     _stateChanged(null, new StateChangedEventArgs(state));
260                 }
261             };
262             int ret = Interop.WiFiDirect.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero);
263             if (ret != (int)WiFiDirectError.None)
264             {
265                 Log.Error(Globals.LogTag, "Failed to set Wi-Fi Direct state changed callback, Error - " + (WiFiDirectError)ret);
266             }
267         }
268
269         private void UnregisterStateChangedEvent()
270         {
271             int ret = Interop.WiFiDirect.UnsetStateChangedCallback();
272             if (ret != (int)WiFiDirectError.None)
273             {
274                 Log.Error(Globals.LogTag, "Failed to unset Wi-Fi Direct state changed callback, Error - " + (WiFiDirectError)ret);
275             }
276         }
277
278         private void RegisterDiscoveryStateChangedEvent()
279         {
280             _discoveryStateChangedCallback = (int result, WiFiDirectDiscoveryState stateInfo, IntPtr userData) =>
281             {
282                 if (_discoveryStateChanged != null)
283                 {
284                     WiFiDirectError error = (WiFiDirectError)result;
285                     WiFiDirectDiscoveryState state = stateInfo;
286                     _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(error, state));
287                 }
288             };
289             int ret = Interop.WiFiDirect.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero);
290             if (ret != (int)WiFiDirectError.None)
291             {
292                 Log.Error(Globals.LogTag, "Failed to set Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
293             }
294         }
295
296         private void UnregisterDiscoveryStateChangedEvent()
297         {
298             int ret = Interop.WiFiDirect.UnsetDiscoveryStateChangedCallback();
299             if (ret != (int)WiFiDirectError.None)
300             {
301                 Log.Error(Globals.LogTag, "Failed to unset Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
302             }
303         }
304
305         private void RegisterPeerFoundEvent()
306         {
307             _peerFoundCallback = (int result, WiFiDirectDiscoveryState stateInfo, string address, IntPtr userData) =>
308             {
309                 if (_peerFound != null)
310                 {
311                     WiFiDirectError error = (WiFiDirectError)result;
312                     WiFiDirectDiscoveryState state = stateInfo;
313                     IntPtr peer;
314                     Interop.WiFiDirect.GetDiscoveredPeerInfo(address, out peer);
315                     DiscoveredPeerStruct peerStruct = (DiscoveredPeerStruct)Marshal.PtrToStructure(peer, typeof(DiscoveredPeerStruct));
316                     _peerFound(null, new PeerFoundEventArgs(error, state, WiFiDirectUtils.ConvertStructToDiscoveredPeer(peerStruct)));
317                 }
318             };
319             int ret = Interop.WiFiDirect.SetPeerFoundCallback(_peerFoundCallback, IntPtr.Zero);
320             if (ret != (int)WiFiDirectError.None)
321             {
322                 Log.Error(Globals.LogTag, "Failed to set Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
323             }
324         }
325
326         private void UnregisterPeerFoundEvent()
327         {
328             int ret = Interop.WiFiDirect.UnsetPeerFoundCallback();
329             if (ret != (int)WiFiDirectError.None)
330             {
331                 Log.Error(Globals.LogTag, "Failed to unset Wi-Fi Direct discovery state changed callback, Error - " + (WiFiDirectError)ret);
332             }
333         }
334
335         private void RegisterDeviceStateChangedEvent()
336         {
337             _deviceStateChangedCallback = (int result, WiFiDirectDeviceState stateInfo, IntPtr userData) =>
338             {
339                 if (_deviceStateChanged != null)
340                 {
341                     WiFiDirectError error = (WiFiDirectError)result;
342                     WiFiDirectDeviceState state = stateInfo;
343                     _deviceStateChanged(null, new DeviceStateChangedEventArgs(error, state));
344                 }
345             };
346             int ret = Interop.WiFiDirect.SetDeviceStateChangedCallback(_deviceStateChangedCallback, IntPtr.Zero);
347             if (ret != (int)WiFiDirectError.None)
348             {
349                 Log.Error(Globals.LogTag, "Failed to set device state changed callback, Error - " + (WiFiDirectError)ret);
350             }
351         }
352
353         private void UnregisterDeviceStateChangedEvent()
354         {
355             int ret = Interop.WiFiDirect.UnsetDeviceStateChangedCallback();
356             if (ret != (int)WiFiDirectError.None)
357             {
358                 Log.Error(Globals.LogTag, "Failed to unset device state changed callback, Error - " + (WiFiDirectError)ret);
359             }
360         }
361
362         private void RegisterConnectionStatusChangedEvent()
363         {
364             _connectionChangedCallback = (int result, WiFiDirectConnectionState stateInfo, string address, IntPtr userData) =>
365             {
366                 if (_connectionStatusChanged != null)
367                 {
368                     WiFiDirectError error = (WiFiDirectError)result;
369                     WiFiDirectConnectionState state = stateInfo;
370
371                     _connectionStatusChanged(null, new ConnectionStatusChangedEventArgs(error, state));
372                 }
373             };
374             int ret = Interop.WiFiDirect.SetConnectionChangedCallback(_connectionChangedCallback, IntPtr.Zero);
375             if (ret != (int)WiFiDirectError.None)
376             {
377                 Log.Error(Globals.LogTag, "Failed to set connection status changed callback, Error - " + (WiFiDirectError)ret);
378             }
379         }
380
381         private void UnregisterConnectionStatusChangedEvent()
382         {
383             int ret = Interop.WiFiDirect.UnsetConnectionChangedCallback();
384             if (ret != (int)WiFiDirectError.None)
385             {
386                 Log.Error(Globals.LogTag, "Failed to unset connection status changed callback, Error - " + (WiFiDirectError)ret);
387             }
388         }
389
390         internal bool IsGroupOwner
391         {
392             get
393             {
394                 bool isGroupOwner;
395                 int ret = Interop.WiFiDirect.IsGroupOwner(out isGroupOwner);
396                 if (ret != (int)WiFiDirectError.None)
397                 {
398                     Log.Error(Globals.LogTag, "Failed to get whether this device is the group owner or not, Error - " + (WiFiDirectError)ret);
399                 }
400
401                 return isGroupOwner;
402             }
403         }
404
405         internal bool IsAutonomousGroup
406         {
407             get
408             {
409                 bool isAutonomousGroup;
410                 int ret = Interop.WiFiDirect.IsAutonomousGroup(out isAutonomousGroup);
411                 if (ret != (int)WiFiDirectError.None)
412                 {
413                     Log.Error(Globals.LogTag, "Failed to check whether the current group is autonomous or not, Error - " + (WiFiDirectError)ret);
414                 }
415
416                 return isAutonomousGroup;
417             }
418         }
419
420         internal string Ssid
421         {
422             get
423             {
424                 string ssid;
425                 int ret = Interop.WiFiDirect.GetSsid(out ssid);
426                 if (ret != (int)WiFiDirectError.None)
427                 {
428                     Log.Error(Globals.LogTag, "Failed to get SSID of local device, Error - " + (WiFiDirectError)ret);
429                     return null;
430                 }
431
432                 return ssid;
433             }
434         }
435
436         internal string NetworkInterface
437         {
438             get
439             {
440                 string networkInterface;
441                 int ret = Interop.WiFiDirect.GetInterfaceName(out networkInterface);
442                 if (ret != (int)WiFiDirectError.None)
443                 {
444                     Log.Error(Globals.LogTag, "Failed to get name of network interface, Error - " + (WiFiDirectError)ret);
445                     return "";
446                 }
447
448                 return networkInterface;
449             }
450         }
451
452         internal string IpAddress
453         {
454             get
455             {
456                 string ipAddress;
457                 int ret = Interop.WiFiDirect.GetIpAddress(out ipAddress);
458                 if (ret != (int)WiFiDirectError.None)
459                 {
460                     Log.Error(Globals.LogTag, "Failed to get IP address of local device, Error - " + (WiFiDirectError)ret);
461                     return "";
462                 }
463
464                 return ipAddress;
465             }
466         }
467
468         internal string SubnetMask
469         {
470             get
471             {
472                 string subnetMask;
473                 int ret = Interop.WiFiDirect.GetSubnetMask(out subnetMask);
474                 if (ret != (int)WiFiDirectError.None)
475                 {
476                     Log.Error(Globals.LogTag, "Failed to get subnet mask, Error - " + (WiFiDirectError)ret);
477                     return "";
478                 }
479
480                 return subnetMask;
481             }
482         }
483
484         internal string GatewayAddress
485         {
486             get
487             {
488                 string gatewayAddress;
489                 int ret = Interop.WiFiDirect.GetGatewayAddress(out gatewayAddress);
490                 if (ret != (int)WiFiDirectError.None)
491                 {
492                     Log.Error(Globals.LogTag, "Failed to get gateway address, Error - " + (WiFiDirectError)ret);
493                     return "";
494                 }
495
496                 return gatewayAddress;
497             }
498         }
499
500         internal string MacAddress
501         {
502             get
503             {
504                 string macAddress;
505                 int ret = Interop.WiFiDirect.GetMacAddress(out macAddress);
506                 if (ret != (int)WiFiDirectError.None)
507                 {
508                     Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiDirectError)ret);
509                     return null;
510                 }
511
512                 return macAddress;
513             }
514         }
515
516         internal WiFiDirectState State
517         {
518             get
519             {
520                 WiFiDirectState state;
521                 int ret = Interop.WiFiDirect.GetState(out state);
522                 if (ret != (int)WiFiDirectError.None)
523                 {
524                     Log.Error(Globals.LogTag, "Failed to get state of Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
525                 }
526
527                 return state;
528             }
529         }
530
531         internal bool IsDiscoverable
532         {
533             get
534             {
535                 bool isDiscoverable;
536                 int ret = Interop.WiFiDirect.IsDiscoverable(out isDiscoverable);
537                 if (ret != (int)WiFiDirectError.None)
538                 {
539                     Log.Error(Globals.LogTag, "Failed to check whether the device is discoverable, Error - " + (WiFiDirectError)ret);
540                 }
541
542                 return isDiscoverable;
543             }
544         }
545
546         internal bool IsListenOnly
547         {
548             get
549             {
550                 bool isListenOnly;
551                 int ret = Interop.WiFiDirect.IsListeningOnly(out isListenOnly);
552                 if (ret != (int)WiFiDirectError.None)
553                 {
554                     Log.Error(Globals.LogTag, "Failed to check whether the local device is listening only, Error - " + (WiFiDirectError)ret);
555                 }
556
557                 return isListenOnly;
558             }
559         }
560
561         internal WiFiDirectPrimaryDeviceType PrimaryType
562         {
563             get
564             {
565                 WiFiDirectPrimaryDeviceType primaryType;
566                 int ret = Interop.WiFiDirect.GetPrimaryType(out primaryType);
567                 if (ret != (int)WiFiDirectError.None)
568                 {
569                     Log.Error(Globals.LogTag, "Failed to get the primary device type of local device, Error - " + (WiFiDirectError)ret);
570                 }
571
572                 return primaryType;
573             }
574         }
575
576         internal WiFiDirectSecondaryDeviceType SecondaryType
577         {
578             get
579             {
580                 WiFiDirectSecondaryDeviceType secondaryType;
581                 int ret = Interop.WiFiDirect.GetSecondaryType(out secondaryType);
582                 if (ret != (int)WiFiDirectError.None)
583                 {
584                     Log.Error(Globals.LogTag, "Failed to get the secondary device type of local device, Error - " + (WiFiDirectError)ret);
585                 }
586
587                 return secondaryType;
588             }
589         }
590
591         internal int WpsMode
592         {
593             get
594             {
595                 int mode;
596                 int ret = Interop.WiFiDirect.GetWpsMode(out mode);
597                 if (ret != (int)WiFiDirectError.None)
598                 {
599                     Log.Error(Globals.LogTag, "Failed to get supproted wps modes at local device, Error - " + (WiFiDirectError)ret);
600                     return -1;
601                 }
602
603                 return mode;
604             }
605         }
606
607         internal WiFiDirectWpsType WpsType
608         {
609             get
610             {
611                 WiFiDirectWpsType wpsType;
612                 int ret = Interop.WiFiDirect.GetLocalWpsType(out wpsType);
613                 if (ret != (int)WiFiDirectError.None)
614                 {
615                     Log.Error(Globals.LogTag, "Failed to get the WPS type, Error - " + (WiFiDirectError)ret);
616                 }
617
618                 return wpsType;
619             }
620         }
621
622         internal int OperatingChannel
623         {
624             get
625             {
626                 int channel;
627                 int ret = Interop.WiFiDirect.GetChannel(out channel);
628                 if (ret != (int)WiFiDirectError.None)
629                 {
630                     Log.Error(Globals.LogTag, "Failed to get operating channel, Error - " + (WiFiDirectError)ret);
631                     return -1;
632                 }
633
634                 return channel;
635             }
636         }
637
638         internal bool PersistentGroupEnabled
639         {
640             get
641             {
642                 bool isEnabled;
643                 int ret = Interop.WiFiDirect.GetPersistentGroupState(out isEnabled);
644                 if (ret != (int)WiFiDirectError.None)
645                 {
646                     Log.Error(Globals.LogTag, "Failed to check persistent group state, Error - " + (WiFiDirectError)ret);
647                 }
648
649                 return isEnabled;
650             }
651
652             set
653             {
654                 int ret = Interop.WiFiDirect.SetPersistentGroupState(value);
655                 if (ret != (int)WiFiDirectError.None)
656                 {
657                     Log.Error(Globals.LogTag, "Failed to set the persistent group state, Error - " + (WiFiDirectError)ret);
658                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
659                 }
660             }
661         }
662
663         internal bool AutoConnect
664         {
665             get
666             {
667                 bool isAutoConnect;
668                 int ret = Interop.WiFiDirect.GetAutoConnectionMode(out isAutoConnect);
669                 if (ret != (int)WiFiDirectError.None)
670                 {
671                     Log.Error(Globals.LogTag, "Failed to get autoconnection mode status, Error - " + (WiFiDirectError)ret);
672                 }
673
674                 return isAutoConnect;
675             }
676
677             set
678             {
679                 int ret = Interop.WiFiDirect.SetAutoConnectionMode(value);
680                 if (ret != (int)WiFiDirectError.None)
681                 {
682                     Log.Error(Globals.LogTag, "Failed to set the autoconnection mode, Error - " + (WiFiDirectError)ret);
683                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
684                 }
685             }
686         }
687
688         internal string WpsPin
689         {
690             get
691             {
692                 string pin;
693                 int ret = Interop.WiFiDirect.GetWpsPin(out pin);
694                 if (ret != (int)WiFiDirectError.None)
695                 {
696                     Log.Error(Globals.LogTag, "Failed to get WPS pin, Error - " + (WiFiDirectError)ret);
697                 }
698
699                 return pin;
700             }
701
702             set
703             {
704                 int ret = Interop.WiFiDirect.SetWpsPin(value.ToString());
705                 if (ret != (int)WiFiDirectError.None)
706                 {
707                     Log.Error(Globals.LogTag, "Failed to set or update WPS pin, Error - " + (WiFiDirectError)ret);
708                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
709                 }
710             }
711         }
712
713         internal string Name
714         {
715             get
716             {
717                 string name;
718                 int ret = Interop.WiFiDirect.GetName(out name);
719                 if (ret != (int)WiFiDirectError.None)
720                 {
721                     Log.Error(Globals.LogTag, "Failed to get name of local device, Error - " + (WiFiDirectError)ret);
722                     return null;
723                 }
724
725                 return name;
726             }
727
728             set
729             {
730                 int ret = Interop.WiFiDirect.SetName(value.ToString());
731                 if (ret != (int)WiFiDirectError.None)
732                 {
733                     Log.Error(Globals.LogTag, "Failed to set name of local device, Error - " + (WiFiDirectError)ret);
734                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
735                 }
736             }
737         }
738
739         internal WiFiDirectWpsType RequestedWps
740         {
741             get
742             {
743                 WiFiDirectWpsType wpsType;
744                 int ret = Interop.WiFiDirect.GetReqWpsType(out wpsType);
745                 if (ret != (int)WiFiDirectError.None)
746                 {
747                     Log.Error(Globals.LogTag, "Failed to get the requested WPS type, Error - " + (WiFiDirectError)ret);
748                 }
749
750                 return wpsType;
751             }
752
753             set
754             {
755                 int ret = Interop.WiFiDirect.SetReqWpsType(value);
756                 if (ret != (int)WiFiDirectError.None)
757                 {
758                     Log.Error(Globals.LogTag, "Failed to set the requested WPS type, Error - " + (WiFiDirectError)ret);
759                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
760                 }
761             }
762         }
763
764         internal int GroupOwnerIntent
765         {
766             get
767             {
768                 int intent;
769                 int ret = Interop.WiFiDirect.GetIntent(out intent);
770                 if (ret != (int)WiFiDirectError.None)
771                 {
772                     Log.Error(Globals.LogTag, "Failed to get the intent of the group owner, Error - " + (WiFiDirectError)ret);
773                 }
774
775                 return intent;
776             }
777
778             set
779             {
780                 int ret = Interop.WiFiDirect.SetIntent(value);
781                 if (ret != (int)WiFiDirectError.None)
782                 {
783                     Log.Error(Globals.LogTag, "Failed to set the intent of the group owner, Error - " + (WiFiDirectError)ret);
784                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
785                 }
786             }
787         }
788
789         internal int MaxClients
790         {
791             get
792             {
793                 int maxClients;
794                 int ret = Interop.WiFiDirect.GetMaxClients(out maxClients);
795                 if (ret != (int)WiFiDirectError.None)
796                 {
797                     Log.Error(Globals.LogTag, "Failed to get the max number of clients, Error - " + (WiFiDirectError)ret);
798                 }
799
800                 return maxClients;
801             }
802
803             set
804             {
805                 int ret = Interop.WiFiDirect.SetMaxClients(value);
806                 if (ret != (int)WiFiDirectError.None)
807                 {
808                     Log.Error(Globals.LogTag, "Failed to set the max number of clients, Error - " + (WiFiDirectError)ret);
809                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
810                 }
811             }
812         }
813
814         internal string Passphrase
815         {
816             get
817             {
818                 string passphrase;
819                 int ret = Interop.WiFiDirect.GetPassPhrase(out passphrase);
820                 if (ret != (int)WiFiDirectError.None)
821                 {
822                     Log.Error(Globals.LogTag, "Failed to get Wi-Fi Protected Access password, Error - " + (WiFiDirectError)ret);
823                     return "";
824                 }
825
826                 return passphrase;
827             }
828
829             set
830             {
831                 int ret = Interop.WiFiDirect.SetPassPhrase(value.ToString());
832                 if (ret != (int)WiFiDirectError.None)
833                 {
834                     Log.Error(Globals.LogTag, "Failed to set or update Wi-Fi Protected Access password, Error - " + (WiFiDirectError)ret);
835                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
836                 }
837             }
838         }
839
840         internal int SessionTimer
841         {
842             get
843             {
844                 int sessionTimer;
845                 int ret = Interop.WiFiDirect.GetSessionTimer(out sessionTimer);
846                 if (ret != (int)WiFiDirectError.None)
847                 {
848                     Log.Error(Globals.LogTag, "Failed to get the timer used to expire the connection session, Error - " + (WiFiDirectError)ret);
849                 }
850
851                 return sessionTimer;
852             }
853
854             set
855             {
856                 int ret = Interop.WiFiDirect.SetSessionTimer(value);
857                 if (ret != (int)WiFiDirectError.None)
858                 {
859                     Log.Error(Globals.LogTag, "Failed to set the timer used to expire the connection session, Error - " + (WiFiDirectError)ret);
860                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
861                 }
862             }
863         }
864
865         internal void Activate()
866         {
867             int ret = Interop.WiFiDirect.Activate();
868             if (ret != (int)WiFiDirectError.None)
869             {
870                 Log.Error(Globals.LogTag, "Failed to activate Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
871                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
872             }
873         }
874
875         internal void Deactivate()
876         {
877             int ret = Interop.WiFiDirect.Deactivate();
878             if (ret != (int)WiFiDirectError.None)
879             {
880                 Log.Error(Globals.LogTag, "Failed to deactivate Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
881                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
882             }
883         }
884
885         internal void StartDiscovery(bool listenOnly, int duration, WiFiDirectDiscoveryChannel channel = WiFiDirectDiscoveryChannel.FullScan)
886         {
887             int ret = Interop.WiFiDirect.StartDiscoveryInChannel(listenOnly, duration, channel);
888             if (ret != (int)WiFiDirectError.None)
889             {
890                 Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (WiFiDirectError)ret);
891                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
892             }
893         }
894
895         internal void CancelDiscovery()
896         {
897             int ret = Interop.WiFiDirect.StopDiscovery();
898             if (ret != (int)WiFiDirectError.None)
899             {
900                 Log.Error(Globals.LogTag, "Failed to cancel discovery, Error - " + (WiFiDirectError)ret);
901                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
902             }
903         }
904
905         internal IEnumerable<WiFiDirectPeer> GetDiscoveredPeers()
906         {
907             List<WiFiDirectPeer> discoveredPeerList = new List<WiFiDirectPeer>();
908             Interop.WiFiDirect.DiscoveredPeerCallback callback = (ref DiscoveredPeerStruct peer, IntPtr userData) =>
909             {
910                 if (!peer.Equals(null))
911                 {
912                     discoveredPeerList.Add(WiFiDirectUtils.ConvertStructToDiscoveredPeer(peer));
913                 }
914
915                 return true;
916             };
917             int ret = Interop.WiFiDirect.GetDiscoveredPeers(callback, IntPtr.Zero);
918             if (ret != (int)WiFiDirectError.None)
919             {
920                 Log.Error(Globals.LogTag, "Failed to get information of discovered peers, Error - " + (WiFiDirectError)ret);
921                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
922             }
923
924             return discoveredPeerList;
925         }
926
927         internal IEnumerable<WiFiDirectPeer> GetConnectedPeers()
928         {
929             List<WiFiDirectPeer> connectedPeerList = new List<WiFiDirectPeer>();
930             Interop.WiFiDirect.ConnectedPeerCallback callback = (ref ConnectedPeerStruct peer, IntPtr userData) =>
931             {
932                 if (!peer.Equals(null))
933                 {
934                     connectedPeerList.Add(WiFiDirectUtils.ConvertStructToConnectedPeer(peer));
935                 }
936
937                 return true;
938             };
939             int ret = Interop.WiFiDirect.GetConnectedPeers(callback, IntPtr.Zero);
940             if (ret != (int)WiFiDirectError.None)
941             {
942                 Log.Error(Globals.LogTag, "Failed to get information of connected peers, Error - " + (WiFiDirectError)ret);
943                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
944             }
945
946             return connectedPeerList;
947         }
948
949         internal void DisconnectAll()
950         {
951             int ret = Interop.WiFiDirect.DisconnectAll();
952             if (ret != (int)WiFiDirectError.None)
953             {
954                 Log.Error(Globals.LogTag, "Failed to disconnect all connected links, Error - " + (WiFiDirectError)ret);
955                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
956             }
957         }
958
959         internal void CreateGroup()
960         {
961             int ret = Interop.WiFiDirect.CreateGroup();
962             if (ret != (int)WiFiDirectError.None)
963             {
964                 Log.Error(Globals.LogTag, "Failed to create a WiFi-Direct group, Error - " + (WiFiDirectError)ret);
965                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
966             }
967         }
968
969         internal void DestroyGroup()
970         {
971             int ret = Interop.WiFiDirect.DestroyGroup();
972             if (ret != (int)WiFiDirectError.None)
973             {
974                 Log.Error(Globals.LogTag, "Failed to destroy the WiFi-Direct group, Error - " + (WiFiDirectError)ret);
975                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
976             }
977         }
978
979         internal void ActivatePushButton()
980         {
981             int ret = Interop.WiFiDirect.ActivatePushButton();
982             if (ret != (int)WiFiDirectError.None)
983             {
984                 Log.Error(Globals.LogTag, "Failed to set the Wps config PBC, Error - " + (WiFiDirectError)ret);
985                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
986             }
987         }
988
989         internal IEnumerable<WiFiDirectWpsType> GetSupportedWpsTypes()
990         {
991             List<WiFiDirectWpsType> wpsList = new List<WiFiDirectWpsType>();
992             Interop.WiFiDirect.WpsTypeCallback callback = (WiFiDirectWpsType type, IntPtr userData) =>
993             {
994                 if (!type.Equals(null))
995                 {
996                     wpsList.Add(type);
997                 }
998
999                 return true;
1000             };
1001             int ret = Interop.WiFiDirect.GetWpsTypes(callback, IntPtr.Zero);
1002             if (ret != (int)WiFiDirectError.None)
1003             {
1004                 Log.Error(Globals.LogTag, "Failed to get the supported WPS types, Error - " + (WiFiDirectError)ret);
1005                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1006             }
1007
1008             return wpsList;
1009         }
1010
1011         internal IEnumerable<WiFiDirectPersistentGroup> GetPersistentGroups()
1012         {
1013             List<WiFiDirectPersistentGroup> persistentGroupList = new List<WiFiDirectPersistentGroup>();
1014             Interop.WiFiDirect.PersistentGroupCallback callback = (string address, string ssid, IntPtr userData) =>
1015             {
1016                 if (address != null && ssid != null)
1017                 {
1018                     persistentGroupList.Add(new WiFiDirectPersistentGroup(address, ssid));
1019                 }
1020
1021                 return true;
1022             };
1023             int ret = Interop.WiFiDirect.GetPersistentGroups(callback, IntPtr.Zero);
1024             if (ret != (int)WiFiDirectError.None)
1025             {
1026                 Log.Error(Globals.LogTag, "Failed to get the persistent groups, Error - " + (WiFiDirectError)ret);
1027                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1028             }
1029
1030             return persistentGroupList;
1031         }
1032
1033         internal void RemovePersistentGroup(WiFiDirectPersistentGroup group)
1034         {
1035             int ret = Interop.WiFiDirect.RemovePersistentGroup(group.MacAddress, group.Ssid);
1036             if (ret != (int)WiFiDirectError.None)
1037             {
1038                 Log.Error(Globals.LogTag, "Failed to remove a persistent group, Error - " + (WiFiDirectError)ret);
1039                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1040             }
1041         }
1042
1043         internal void InitMiracast(bool enable)
1044         {
1045             int ret = Interop.WiFiDirect.InitMiracast(enable);
1046             if (ret != (int)WiFiDirectError.None)
1047             {
1048                 Log.Error(Globals.LogTag, "Failed to set the WiFi-Direct Display(MIRACAST) service, Error - " + (WiFiDirectError)ret);
1049                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1050             }
1051         }
1052
1053         internal void InitDisplay()
1054         {
1055             int ret = Interop.WiFiDirect.InitDisplay();
1056             if (ret != (int)WiFiDirectError.None)
1057             {
1058                 Log.Error(Globals.LogTag, "Failed to enable Wi-Fi Display functionality, Error - " + (WiFiDirectError)ret);
1059                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1060             }
1061
1062             else
1063             {
1064                 Globals.s_isDisplay = true;
1065             }
1066         }
1067
1068         internal void DeinitDisplay()
1069         {
1070             int ret = Interop.WiFiDirect.DeinitDisplay();
1071             if (ret != (int)WiFiDirectError.None)
1072             {
1073                 Log.Error(Globals.LogTag, "Failed to disable Wi-Fi Display functionality, Error - " + (WiFiDirectError)ret);
1074                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1075             }
1076
1077             else
1078             {
1079                 Globals.s_isDisplay = false;
1080             }
1081         }
1082
1083         internal void SetDisplay(WiFiDirectDisplayType type, int port, int hdcp)
1084         {
1085             int ret = Interop.WiFiDirect.SetDisplay(type, port, hdcp);
1086             if (ret != (int)WiFiDirectError.None)
1087             {
1088                 Log.Error(Globals.LogTag, "Failed to set the Wi-Fi Display parameters, Error - " + (WiFiDirectError)ret);
1089                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1090             }
1091         }
1092
1093         internal void SetDisplayAvailability(bool availability)
1094         {
1095             int ret = Interop.WiFiDirect.SetDisplayAvailability(availability);
1096             if (ret != (int)WiFiDirectError.None)
1097             {
1098                 Log.Error(Globals.LogTag, "Failed to set the Wi-Fi Display session availability, Error - " + (WiFiDirectError)ret);
1099                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1100             }
1101         }
1102
1103         internal void SetAutoGroupRemove(bool enable)
1104         {
1105             int ret = Interop.WiFiDirect.SetAutoGroupRemoval(enable);
1106             if (ret != (int)WiFiDirectError.None)
1107             {
1108                 Log.Error(Globals.LogTag, "Failed to set automatic group removal feature when all peers are disconnected, Error - " + (WiFiDirectError)ret);
1109                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1110             }
1111         }
1112
1113         internal uint RegisterService(WiFiDirectServiceType type, string info, string serviceInfo)
1114         {
1115             uint serviceId;
1116             int ret = Interop.WiFiDirect.RegisterService(type, info, serviceInfo, out serviceId);
1117             if (ret != (int)WiFiDirectError.None)
1118             {
1119                 Log.Error(Globals.LogTag, "Failed to register for service, Error - " + (WiFiDirectError)ret);
1120                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1121             }
1122
1123             return serviceId;
1124         }
1125
1126         internal void DeregisterService(uint serviceId)
1127         {
1128             int ret = Interop.WiFiDirect.DeregisterService(serviceId);
1129             if (ret != (int)WiFiDirectError.None)
1130             {
1131                 Log.Error(Globals.LogTag, "Failed to deregister service, Error - " + (WiFiDirectError)ret);
1132                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1133             }
1134         }
1135
1136         internal static WiFiDirectManagerImpl Instance
1137         {
1138             get
1139             {
1140                 if (_instance == null)
1141                 {
1142                     _instance = new WiFiDirectManagerImpl();
1143                 }
1144
1145                 return _instance;
1146             }
1147         }
1148
1149         private WiFiDirectManagerImpl()
1150         {
1151         }
1152
1153         internal void Initialize()
1154         {
1155             int ret = Interop.WiFiDirect.Initialize();
1156             if (ret != (int)WiFiDirectError.None)
1157             {
1158                 Log.Error(Globals.LogTag, "Failed to initialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
1159                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1160             }
1161
1162             else
1163             {
1164                 Globals.s_isInitialize = true;
1165             }
1166         }
1167
1168         ~WiFiDirectManagerImpl()
1169         {
1170             Dispose(false);
1171         }
1172
1173         public void Dispose()
1174         {
1175             Dispose(true);
1176             GC.SuppressFinalize(this);
1177         }
1178
1179         private void Dispose(bool disposing)
1180         {
1181             if (_disposed)
1182             {
1183                 return;
1184             }
1185
1186             if (disposing)
1187             {
1188                 // Free managed objects.
1189             }
1190
1191             //Free unmanaged objects
1192             RemoveAllRegisteredEvent();
1193             Deinitialize();
1194             _disposed = true;
1195         }
1196
1197         private void Deinitialize()
1198         {
1199             int ret = Interop.WiFiDirect.Deinitialize();
1200             if (ret != (int)WiFiDirectError.None)
1201             {
1202                 Log.Error(Globals.LogTag, "Failed to deinitialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
1203                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1204             }
1205
1206             else
1207             {
1208                 Globals.s_isInitialize = false;
1209             }
1210         }
1211
1212         private void RemoveAllRegisteredEvent()
1213         {
1214             //unregister all remaining events when this object is released.
1215             if (_stateChanged != null)
1216             {
1217                 UnregisterStateChangedEvent();
1218             }
1219
1220             if (_discoveryStateChanged != null)
1221             {
1222                 UnregisterDiscoveryStateChangedEvent();
1223             }
1224
1225             if (_peerFound != null)
1226             {
1227                 UnregisterPeerFoundEvent();
1228             }
1229
1230             if (_deviceStateChanged != null)
1231             {
1232                 UnregisterDeviceStateChangedEvent();
1233             }
1234
1235             if (_connectionStatusChanged != null)
1236             {
1237                 UnregisterConnectionStatusChangedEvent();
1238             }
1239         }
1240     }
1241 }