Release 4.0.0-preview1-00051
[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 IsInitialize
391         {
392                 get
393                 {
394                     return Globals.IsInitialize;
395                 }
396         }
397         internal bool IsGroupOwner
398         {
399             get
400             {
401                 bool isGroupOwner;
402                 int ret = Interop.WiFiDirect.IsGroupOwner(out isGroupOwner);
403                 if (ret != (int)WiFiDirectError.None)
404                 {
405                     Log.Error(Globals.LogTag, "Failed to get whether this device is the group owner or not, Error - " + (WiFiDirectError)ret);
406                 }
407
408                 return isGroupOwner;
409             }
410         }
411
412         internal bool IsAutonomousGroup
413         {
414             get
415             {
416                 bool isAutonomousGroup;
417                 int ret = Interop.WiFiDirect.IsAutonomousGroup(out isAutonomousGroup);
418                 if (ret != (int)WiFiDirectError.None)
419                 {
420                     Log.Error(Globals.LogTag, "Failed to check whether the current group is autonomous or not, Error - " + (WiFiDirectError)ret);
421                 }
422
423                 return isAutonomousGroup;
424             }
425         }
426
427         internal string Ssid
428         {
429             get
430             {
431                 string ssid;
432                 int ret = Interop.WiFiDirect.GetSsid(out ssid);
433                 if (ret != (int)WiFiDirectError.None)
434                 {
435                     Log.Error(Globals.LogTag, "Failed to get SSID of local device, Error - " + (WiFiDirectError)ret);
436                     return null;
437                 }
438
439                 return ssid;
440             }
441         }
442
443         internal string NetworkInterface
444         {
445             get
446             {
447                 string networkInterface;
448                 int ret = Interop.WiFiDirect.GetInterfaceName(out networkInterface);
449                 if (ret != (int)WiFiDirectError.None)
450                 {
451                     Log.Error(Globals.LogTag, "Failed to get name of network interface, Error - " + (WiFiDirectError)ret);
452                     return "";
453                 }
454
455                 return networkInterface;
456             }
457         }
458
459         internal string IpAddress
460         {
461             get
462             {
463                 string ipAddress;
464                 int ret = Interop.WiFiDirect.GetIpAddress(out ipAddress);
465                 if (ret != (int)WiFiDirectError.None)
466                 {
467                     Log.Error(Globals.LogTag, "Failed to get IP address of local device, Error - " + (WiFiDirectError)ret);
468                     return "";
469                 }
470
471                 return ipAddress;
472             }
473         }
474
475         internal string SubnetMask
476         {
477             get
478             {
479                 string subnetMask;
480                 int ret = Interop.WiFiDirect.GetSubnetMask(out subnetMask);
481                 if (ret != (int)WiFiDirectError.None)
482                 {
483                     Log.Error(Globals.LogTag, "Failed to get subnet mask, Error - " + (WiFiDirectError)ret);
484                     return "";
485                 }
486
487                 return subnetMask;
488             }
489         }
490
491         internal string GatewayAddress
492         {
493             get
494             {
495                 string gatewayAddress;
496                 int ret = Interop.WiFiDirect.GetGatewayAddress(out gatewayAddress);
497                 if (ret != (int)WiFiDirectError.None)
498                 {
499                     Log.Error(Globals.LogTag, "Failed to get gateway address, Error - " + (WiFiDirectError)ret);
500                     return "";
501                 }
502
503                 return gatewayAddress;
504             }
505         }
506
507         internal string MacAddress
508         {
509             get
510             {
511                 string macAddress;
512                 int ret = Interop.WiFiDirect.GetMacAddress(out macAddress);
513                 if (ret != (int)WiFiDirectError.None)
514                 {
515                     Log.Error(Globals.LogTag, "Failed to get mac address, Error - " + (WiFiDirectError)ret);
516                     return null;
517                 }
518
519                 return macAddress;
520             }
521         }
522
523         internal WiFiDirectState State
524         {
525             get
526             {
527                 WiFiDirectState state;
528                 int ret = Interop.WiFiDirect.GetState(out state);
529                 if (ret != (int)WiFiDirectError.None)
530                 {
531                     Log.Error(Globals.LogTag, "Failed to get state of Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
532                 }
533
534                 return state;
535             }
536         }
537
538         internal bool IsDiscoverable
539         {
540             get
541             {
542                 bool isDiscoverable;
543                 int ret = Interop.WiFiDirect.IsDiscoverable(out isDiscoverable);
544                 if (ret != (int)WiFiDirectError.None)
545                 {
546                     Log.Error(Globals.LogTag, "Failed to check whether the device is discoverable, Error - " + (WiFiDirectError)ret);
547                 }
548
549                 return isDiscoverable;
550             }
551         }
552
553         internal bool IsListenOnly
554         {
555             get
556             {
557                 bool isListenOnly;
558                 int ret = Interop.WiFiDirect.IsListeningOnly(out isListenOnly);
559                 if (ret != (int)WiFiDirectError.None)
560                 {
561                     Log.Error(Globals.LogTag, "Failed to check whether the local device is listening only, Error - " + (WiFiDirectError)ret);
562                 }
563
564                 return isListenOnly;
565             }
566         }
567
568         internal WiFiDirectPrimaryDeviceType PrimaryType
569         {
570             get
571             {
572                 WiFiDirectPrimaryDeviceType primaryType;
573                 int ret = Interop.WiFiDirect.GetPrimaryType(out primaryType);
574                 if (ret != (int)WiFiDirectError.None)
575                 {
576                     Log.Error(Globals.LogTag, "Failed to get the primary device type of local device, Error - " + (WiFiDirectError)ret);
577                 }
578
579                 return primaryType;
580             }
581         }
582
583         internal WiFiDirectSecondaryDeviceType SecondaryType
584         {
585             get
586             {
587                 WiFiDirectSecondaryDeviceType secondaryType;
588                 int ret = Interop.WiFiDirect.GetSecondaryType(out secondaryType);
589                 if (ret != (int)WiFiDirectError.None)
590                 {
591                     Log.Error(Globals.LogTag, "Failed to get the secondary device type of local device, Error - " + (WiFiDirectError)ret);
592                 }
593
594                 return secondaryType;
595             }
596         }
597
598         internal int WpsMode
599         {
600             get
601             {
602                 int mode;
603                 int ret = Interop.WiFiDirect.GetWpsMode(out mode);
604                 if (ret != (int)WiFiDirectError.None)
605                 {
606                     Log.Error(Globals.LogTag, "Failed to get supproted wps modes at local device, Error - " + (WiFiDirectError)ret);
607                     return -1;
608                 }
609
610                 return mode;
611             }
612         }
613
614         internal WiFiDirectWpsType WpsType
615         {
616             get
617             {
618                 WiFiDirectWpsType wpsType;
619                 int ret = Interop.WiFiDirect.GetLocalWpsType(out wpsType);
620                 if (ret != (int)WiFiDirectError.None)
621                 {
622                     Log.Error(Globals.LogTag, "Failed to get the WPS type, Error - " + (WiFiDirectError)ret);
623                 }
624
625                 return wpsType;
626             }
627         }
628
629         internal int OperatingChannel
630         {
631             get
632             {
633                 int channel;
634                 int ret = Interop.WiFiDirect.GetChannel(out channel);
635                 if (ret != (int)WiFiDirectError.None)
636                 {
637                     Log.Error(Globals.LogTag, "Failed to get operating channel, Error - " + (WiFiDirectError)ret);
638                     return -1;
639                 }
640
641                 return channel;
642             }
643         }
644
645         internal bool PersistentGroupEnabled
646         {
647             get
648             {
649                 bool isEnabled;
650                 int ret = Interop.WiFiDirect.GetPersistentGroupState(out isEnabled);
651                 if (ret != (int)WiFiDirectError.None)
652                 {
653                     Log.Error(Globals.LogTag, "Failed to check persistent group state, Error - " + (WiFiDirectError)ret);
654                 }
655
656                 return isEnabled;
657             }
658
659             set
660             {
661                 int ret = Interop.WiFiDirect.SetPersistentGroupState(value);
662                 if (ret != (int)WiFiDirectError.None)
663                 {
664                     Log.Error(Globals.LogTag, "Failed to set the persistent group state, Error - " + (WiFiDirectError)ret);
665                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
666                 }
667             }
668         }
669
670         internal bool AutoConnect
671         {
672             get
673             {
674                 bool isAutoConnect;
675                 int ret = Interop.WiFiDirect.GetAutoConnectionMode(out isAutoConnect);
676                 if (ret != (int)WiFiDirectError.None)
677                 {
678                     Log.Error(Globals.LogTag, "Failed to get autoconnection mode status, Error - " + (WiFiDirectError)ret);
679                 }
680
681                 return isAutoConnect;
682             }
683
684             set
685             {
686                 int ret = Interop.WiFiDirect.SetAutoConnectionMode(value);
687                 if (ret != (int)WiFiDirectError.None)
688                 {
689                     Log.Error(Globals.LogTag, "Failed to set the autoconnection mode, Error - " + (WiFiDirectError)ret);
690                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
691                 }
692             }
693         }
694
695         internal string WpsPin
696         {
697             get
698             {
699                 string pin;
700                 int ret = Interop.WiFiDirect.GetWpsPin(out pin);
701                 if (ret != (int)WiFiDirectError.None)
702                 {
703                     Log.Error(Globals.LogTag, "Failed to get WPS pin, Error - " + (WiFiDirectError)ret);
704                 }
705
706                 return pin;
707             }
708
709             set
710             {
711                 int ret = Interop.WiFiDirect.SetWpsPin(value.ToString());
712                 if (ret != (int)WiFiDirectError.None)
713                 {
714                     Log.Error(Globals.LogTag, "Failed to set or update WPS pin, Error - " + (WiFiDirectError)ret);
715                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
716                 }
717             }
718         }
719
720         internal string Name
721         {
722             get
723             {
724                 string name;
725                 int ret = Interop.WiFiDirect.GetName(out name);
726                 if (ret != (int)WiFiDirectError.None)
727                 {
728                     Log.Error(Globals.LogTag, "Failed to get name of local device, Error - " + (WiFiDirectError)ret);
729                     return null;
730                 }
731
732                 return name;
733             }
734
735             set
736             {
737                 int ret = Interop.WiFiDirect.SetName(value.ToString());
738                 if (ret != (int)WiFiDirectError.None)
739                 {
740                     Log.Error(Globals.LogTag, "Failed to set name of local device, Error - " + (WiFiDirectError)ret);
741                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
742                 }
743             }
744         }
745
746         internal WiFiDirectWpsType RequestedWps
747         {
748             get
749             {
750                 WiFiDirectWpsType wpsType;
751                 int ret = Interop.WiFiDirect.GetReqWpsType(out wpsType);
752                 if (ret != (int)WiFiDirectError.None)
753                 {
754                     Log.Error(Globals.LogTag, "Failed to get the requested WPS type, Error - " + (WiFiDirectError)ret);
755                 }
756
757                 return wpsType;
758             }
759
760             set
761             {
762                 int ret = Interop.WiFiDirect.SetReqWpsType(value);
763                 if (ret != (int)WiFiDirectError.None)
764                 {
765                     Log.Error(Globals.LogTag, "Failed to set the requested WPS type, Error - " + (WiFiDirectError)ret);
766                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
767                 }
768             }
769         }
770
771         internal int GroupOwnerIntent
772         {
773             get
774             {
775                 int intent;
776                 int ret = Interop.WiFiDirect.GetIntent(out intent);
777                 if (ret != (int)WiFiDirectError.None)
778                 {
779                     Log.Error(Globals.LogTag, "Failed to get the intent of the group owner, Error - " + (WiFiDirectError)ret);
780                 }
781
782                 return intent;
783             }
784
785             set
786             {
787                 int ret = Interop.WiFiDirect.SetIntent(value);
788                 if (ret != (int)WiFiDirectError.None)
789                 {
790                     Log.Error(Globals.LogTag, "Failed to set the intent of the group owner, Error - " + (WiFiDirectError)ret);
791                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
792                 }
793             }
794         }
795
796         internal int MaxClients
797         {
798             get
799             {
800                 int maxClients;
801                 int ret = Interop.WiFiDirect.GetMaxClients(out maxClients);
802                 if (ret != (int)WiFiDirectError.None)
803                 {
804                     Log.Error(Globals.LogTag, "Failed to get the max number of clients, Error - " + (WiFiDirectError)ret);
805                 }
806
807                 return maxClients;
808             }
809
810             set
811             {
812                 int ret = Interop.WiFiDirect.SetMaxClients(value);
813                 if (ret != (int)WiFiDirectError.None)
814                 {
815                     Log.Error(Globals.LogTag, "Failed to set the max number of clients, Error - " + (WiFiDirectError)ret);
816                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
817                 }
818             }
819         }
820
821         internal string Passphrase
822         {
823             get
824             {
825                 string passphrase;
826                 int ret = Interop.WiFiDirect.GetPassPhrase(out passphrase);
827                 if (ret != (int)WiFiDirectError.None)
828                 {
829                     Log.Error(Globals.LogTag, "Failed to get Wi-Fi Protected Access password, Error - " + (WiFiDirectError)ret);
830                     return "";
831                 }
832
833                 return passphrase;
834             }
835
836             set
837             {
838                 int ret = Interop.WiFiDirect.SetPassPhrase(value.ToString());
839                 if (ret != (int)WiFiDirectError.None)
840                 {
841                     Log.Error(Globals.LogTag, "Failed to set or update Wi-Fi Protected Access password, Error - " + (WiFiDirectError)ret);
842                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
843                 }
844             }
845         }
846
847         internal int SessionTimer
848         {
849             get
850             {
851                 int sessionTimer;
852                 int ret = Interop.WiFiDirect.GetSessionTimer(out sessionTimer);
853                 if (ret != (int)WiFiDirectError.None)
854                 {
855                     Log.Error(Globals.LogTag, "Failed to get the timer used to expire the connection session, Error - " + (WiFiDirectError)ret);
856                 }
857
858                 return sessionTimer;
859             }
860
861             set
862             {
863                 int ret = Interop.WiFiDirect.SetSessionTimer(value);
864                 if (ret != (int)WiFiDirectError.None)
865                 {
866                     Log.Error(Globals.LogTag, "Failed to set the timer used to expire the connection session, Error - " + (WiFiDirectError)ret);
867                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
868                 }
869             }
870         }
871
872         internal void Activate()
873         {
874             int ret = Interop.WiFiDirect.Activate();
875             if (ret != (int)WiFiDirectError.None)
876             {
877                 Log.Error(Globals.LogTag, "Failed to activate Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
878                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
879             }
880         }
881
882         internal void Deactivate()
883         {
884             int ret = Interop.WiFiDirect.Deactivate();
885             if (ret != (int)WiFiDirectError.None)
886             {
887                 Log.Error(Globals.LogTag, "Failed to deactivate Wi-Fi direct service, Error - " + (WiFiDirectError)ret);
888                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
889             }
890         }
891
892         internal void StartDiscovery(bool listenOnly, int duration, WiFiDirectDiscoveryChannel channel = WiFiDirectDiscoveryChannel.FullScan)
893         {
894             int ret = Interop.WiFiDirect.StartDiscoveryInChannel(listenOnly, duration, channel);
895             if (ret != (int)WiFiDirectError.None)
896             {
897                 Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (WiFiDirectError)ret);
898                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
899             }
900         }
901
902         internal void CancelDiscovery()
903         {
904             int ret = Interop.WiFiDirect.StopDiscovery();
905             if (ret != (int)WiFiDirectError.None)
906             {
907                 Log.Error(Globals.LogTag, "Failed to cancel discovery, Error - " + (WiFiDirectError)ret);
908                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
909             }
910         }
911
912         internal IEnumerable<WiFiDirectPeer> GetDiscoveredPeers()
913         {
914             List<WiFiDirectPeer> discoveredPeerList = new List<WiFiDirectPeer>();
915             Interop.WiFiDirect.DiscoveredPeerCallback callback = (ref DiscoveredPeerStruct peer, IntPtr userData) =>
916             {
917                 if (!peer.Equals(null))
918                 {
919                     discoveredPeerList.Add(WiFiDirectUtils.ConvertStructToDiscoveredPeer(peer));
920                 }
921
922                 return true;
923             };
924             int ret = Interop.WiFiDirect.GetDiscoveredPeers(callback, IntPtr.Zero);
925             if (ret != (int)WiFiDirectError.None)
926             {
927                 Log.Error(Globals.LogTag, "Failed to get information of discovered peers, Error - " + (WiFiDirectError)ret);
928                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
929             }
930
931             return discoveredPeerList;
932         }
933
934         internal IEnumerable<WiFiDirectPeer> GetConnectedPeers()
935         {
936             List<WiFiDirectPeer> connectedPeerList = new List<WiFiDirectPeer>();
937             Interop.WiFiDirect.ConnectedPeerCallback callback = (ref ConnectedPeerStruct peer, IntPtr userData) =>
938             {
939                 if (!peer.Equals(null))
940                 {
941                     connectedPeerList.Add(WiFiDirectUtils.ConvertStructToConnectedPeer(peer));
942                 }
943
944                 return true;
945             };
946             int ret = Interop.WiFiDirect.GetConnectedPeers(callback, IntPtr.Zero);
947             if (ret != (int)WiFiDirectError.None)
948             {
949                 Log.Error(Globals.LogTag, "Failed to get information of connected peers, Error - " + (WiFiDirectError)ret);
950                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
951             }
952
953             return connectedPeerList;
954         }
955
956         internal void DisconnectAll()
957         {
958             int ret = Interop.WiFiDirect.DisconnectAll();
959             if (ret != (int)WiFiDirectError.None)
960             {
961                 Log.Error(Globals.LogTag, "Failed to disconnect all connected links, Error - " + (WiFiDirectError)ret);
962                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
963             }
964         }
965
966         internal void CreateGroup()
967         {
968             int ret = Interop.WiFiDirect.CreateGroup();
969             if (ret != (int)WiFiDirectError.None)
970             {
971                 Log.Error(Globals.LogTag, "Failed to create a WiFi-Direct group, Error - " + (WiFiDirectError)ret);
972                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
973             }
974         }
975
976         internal void DestroyGroup()
977         {
978             int ret = Interop.WiFiDirect.DestroyGroup();
979             if (ret != (int)WiFiDirectError.None)
980             {
981                 Log.Error(Globals.LogTag, "Failed to destroy the WiFi-Direct group, Error - " + (WiFiDirectError)ret);
982                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
983             }
984         }
985
986         internal void ActivatePushButton()
987         {
988             int ret = Interop.WiFiDirect.ActivatePushButton();
989             if (ret != (int)WiFiDirectError.None)
990             {
991                 Log.Error(Globals.LogTag, "Failed to set the Wps config PBC, Error - " + (WiFiDirectError)ret);
992                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
993             }
994         }
995
996         internal IEnumerable<WiFiDirectWpsType> GetSupportedWpsTypes()
997         {
998             List<WiFiDirectWpsType> wpsList = new List<WiFiDirectWpsType>();
999             Interop.WiFiDirect.WpsTypeCallback callback = (WiFiDirectWpsType type, IntPtr userData) =>
1000             {
1001                 if (!type.Equals(null))
1002                 {
1003                     wpsList.Add(type);
1004                 }
1005
1006                 return true;
1007             };
1008             int ret = Interop.WiFiDirect.GetWpsTypes(callback, IntPtr.Zero);
1009             if (ret != (int)WiFiDirectError.None)
1010             {
1011                 Log.Error(Globals.LogTag, "Failed to get the supported WPS types, Error - " + (WiFiDirectError)ret);
1012                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1013             }
1014
1015             return wpsList;
1016         }
1017
1018         internal IEnumerable<WiFiDirectPersistentGroup> GetPersistentGroups()
1019         {
1020             List<WiFiDirectPersistentGroup> persistentGroupList = new List<WiFiDirectPersistentGroup>();
1021             Interop.WiFiDirect.PersistentGroupCallback callback = (string address, string ssid, IntPtr userData) =>
1022             {
1023                 if (address != null && ssid != null)
1024                 {
1025                     persistentGroupList.Add(new WiFiDirectPersistentGroup(address, ssid));
1026                 }
1027
1028                 return true;
1029             };
1030             int ret = Interop.WiFiDirect.GetPersistentGroups(callback, IntPtr.Zero);
1031             if (ret != (int)WiFiDirectError.None)
1032             {
1033                 Log.Error(Globals.LogTag, "Failed to get the persistent groups, Error - " + (WiFiDirectError)ret);
1034                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1035             }
1036
1037             return persistentGroupList;
1038         }
1039
1040         internal void RemovePersistentGroup(WiFiDirectPersistentGroup group)
1041         {
1042             int ret = Interop.WiFiDirect.RemovePersistentGroup(group.MacAddress, group.Ssid);
1043             if (ret != (int)WiFiDirectError.None)
1044             {
1045                 Log.Error(Globals.LogTag, "Failed to remove a persistent group, Error - " + (WiFiDirectError)ret);
1046                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1047             }
1048         }
1049
1050         internal void InitMiracast(bool enable)
1051         {
1052             int ret = Interop.WiFiDirect.InitMiracast(enable);
1053             if (ret != (int)WiFiDirectError.None)
1054             {
1055                 Log.Error(Globals.LogTag, "Failed to set the WiFi-Direct Display(MIRACAST) service, Error - " + (WiFiDirectError)ret);
1056                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1057             }
1058         }
1059
1060         internal void InitDisplay()
1061         {
1062             int ret = Interop.WiFiDirect.InitDisplay();
1063             if (ret != (int)WiFiDirectError.None)
1064             {
1065                 Log.Error(Globals.LogTag, "Failed to enable Wi-Fi Display functionality, Error - " + (WiFiDirectError)ret);
1066                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1067             }
1068
1069             else
1070             {
1071                 Globals.s_isDisplay = true;
1072             }
1073         }
1074
1075         internal void DeinitDisplay()
1076         {
1077             int ret = Interop.WiFiDirect.DeinitDisplay();
1078             if (ret != (int)WiFiDirectError.None)
1079             {
1080                 Log.Error(Globals.LogTag, "Failed to disable Wi-Fi Display functionality, Error - " + (WiFiDirectError)ret);
1081                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1082             }
1083
1084             else
1085             {
1086                 Globals.s_isDisplay = false;
1087             }
1088         }
1089
1090         internal void SetDisplay(WiFiDirectDisplayType type, int port, int hdcp)
1091         {
1092             int ret = Interop.WiFiDirect.SetDisplay(type, port, hdcp);
1093             if (ret != (int)WiFiDirectError.None)
1094             {
1095                 Log.Error(Globals.LogTag, "Failed to set the Wi-Fi Display parameters, Error - " + (WiFiDirectError)ret);
1096                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1097             }
1098         }
1099
1100         internal void SetDisplayAvailability(bool availability)
1101         {
1102             int ret = Interop.WiFiDirect.SetDisplayAvailability(availability);
1103             if (ret != (int)WiFiDirectError.None)
1104             {
1105                 Log.Error(Globals.LogTag, "Failed to set the Wi-Fi Display session availability, Error - " + (WiFiDirectError)ret);
1106                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1107             }
1108         }
1109
1110         internal void SetAutoGroupRemove(bool enable)
1111         {
1112             int ret = Interop.WiFiDirect.SetAutoGroupRemoval(enable);
1113             if (ret != (int)WiFiDirectError.None)
1114             {
1115                 Log.Error(Globals.LogTag, "Failed to set automatic group removal feature when all peers are disconnected, Error - " + (WiFiDirectError)ret);
1116                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1117             }
1118         }
1119
1120         internal uint RegisterService(WiFiDirectServiceType type, string info, string serviceInfo)
1121         {
1122             uint serviceId;
1123             int ret = Interop.WiFiDirect.RegisterService(type, info, serviceInfo, out serviceId);
1124             if (ret != (int)WiFiDirectError.None)
1125             {
1126                 Log.Error(Globals.LogTag, "Failed to register for service, Error - " + (WiFiDirectError)ret);
1127                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1128             }
1129
1130             return serviceId;
1131         }
1132
1133         internal void DeregisterService(uint serviceId)
1134         {
1135             int ret = Interop.WiFiDirect.DeregisterService(serviceId);
1136             if (ret != (int)WiFiDirectError.None)
1137             {
1138                 Log.Error(Globals.LogTag, "Failed to deregister service, Error - " + (WiFiDirectError)ret);
1139                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1140             }
1141         }
1142
1143         internal static WiFiDirectManagerImpl Instance
1144         {
1145             get
1146             {
1147                 if (_instance == null)
1148                 {
1149                     _instance = new WiFiDirectManagerImpl();
1150                 }
1151
1152                 return _instance;
1153             }
1154         }
1155
1156         private WiFiDirectManagerImpl()
1157         {
1158         }
1159
1160         internal void Initialize()
1161         {
1162             int ret = Interop.WiFiDirect.Initialize();
1163             if (ret != (int)WiFiDirectError.None)
1164             {
1165                 Log.Error(Globals.LogTag, "Failed to initialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
1166                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1167             }
1168
1169             else
1170             {
1171                 Globals.s_isInitialize = true;
1172             }
1173         }
1174
1175         ~WiFiDirectManagerImpl()
1176         {
1177             Dispose(false);
1178         }
1179
1180         public void Dispose()
1181         {
1182             Dispose(true);
1183             GC.SuppressFinalize(this);
1184         }
1185
1186         private void Dispose(bool disposing)
1187         {
1188             if (_disposed)
1189             {
1190                 return;
1191             }
1192
1193             if (disposing)
1194             {
1195                 // Free managed objects.
1196             }
1197
1198             //Free unmanaged objects
1199             RemoveAllRegisteredEvent();
1200             Deinitialize();
1201             _disposed = true;
1202         }
1203
1204         private void Deinitialize()
1205         {
1206             int ret = Interop.WiFiDirect.Deinitialize();
1207             if (ret != (int)WiFiDirectError.None)
1208             {
1209                 Log.Error(Globals.LogTag, "Failed to deinitialize Wi-Fi direct, Error - " + (WiFiDirectError)ret);
1210                 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
1211             }
1212
1213             else
1214             {
1215                 Globals.s_isInitialize = false;
1216             }
1217         }
1218
1219         private void RemoveAllRegisteredEvent()
1220         {
1221             //unregister all remaining events when this object is released.
1222             if (_stateChanged != null)
1223             {
1224                 UnregisterStateChangedEvent();
1225             }
1226
1227             if (_discoveryStateChanged != null)
1228             {
1229                 UnregisterDiscoveryStateChangedEvent();
1230             }
1231
1232             if (_peerFound != null)
1233             {
1234                 UnregisterPeerFoundEvent();
1235             }
1236
1237             if (_deviceStateChanged != null)
1238             {
1239                 UnregisterDeviceStateChangedEvent();
1240             }
1241
1242             if (_connectionStatusChanged != null)
1243             {
1244                 UnregisterConnectionStatusChangedEvent();
1245             }
1246         }
1247     }
1248 }