[C# Wi-Fi Direct] Adding C# Wi-Fi Direct code
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.WiFiDirect / Tizen.Network.WiFiDirect / WiFiDirectPeer.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.Collections.Concurrent;
21 using System.Collections.ObjectModel;
22 using System.Collections.Specialized;
23
24 namespace Tizen.Network.WiFiDirect
25 {
26     /// <summary>
27     /// WiFiDirectPeer class is used to handle the connection with remote devices using WiFi Direct.
28     /// </summary>
29     /// <privilege> http://tizen.org/privilege/wifidirect </privilege>
30     public class WiFiDirectPeer
31     {
32         private event EventHandler<ConnectionStateChangedEventArgs> _connectionStateChanged;
33         private event EventHandler<IpAddressAssignedEventArgs> _ipAddressAssigned;
34         private event EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
35
36         private Interop.WiFiDirect.ConnectionStateChangedCallback _connectionStateChangedCallback;
37         private Interop.WiFiDirect.ClientIpAddressAssignedCallback _ipAddressAssignedCallback;
38         private Interop.WiFiDirect.ServiceStateChangedCallback _serviceStateChangedCallback;
39
40         internal string _peerDeviceName;
41         internal string _peerIpAddress;
42         internal string _peerMacAddress;
43         internal string _peerInterfaceAddress;
44         internal int _peerChannel;
45         internal bool _isPeerConnected;
46         internal bool _isPeerGroupOwner;
47         internal bool _isPeerPersistentGroupOwner;
48         internal bool _peerP2PSupport;
49         internal WiFiDirectPrimaryDeviceType _peerPrimaryType;
50         internal WiFiDirectSecondaryDeviceType _peerSecondaryType;
51         internal int _peerWpsTypes;
52         internal bool _p2PInvitationSupported;
53         internal uint _peerServiceCount;
54         internal IEnumerable<string> _peerServiceList;
55         internal bool _isPeerMiracastDevice;
56
57         internal WiFiDirectPeer()
58         {
59         }
60
61         /// <summary>
62         /// Name of Peer device.
63         /// </summary>
64         public string Name
65         {
66             get
67             {
68                 return _peerDeviceName;
69             }
70         }
71
72         /// <summary>
73         /// Ip address of the peer device.
74         /// </summary>
75         public string IpAddress
76         {
77             get
78             {
79                 return _peerIpAddress;
80             }
81         }
82
83         /// <summary>
84         /// Mac address of the peer device.
85         /// </summary>
86         public string MacAddress
87         {
88             get
89             {
90                 return _peerMacAddress;
91             }
92         }
93
94         /// <summary>
95         /// Interface address of the peer device.
96         /// </summary>
97         public string InterfaceAddress
98         {
99             get
100             {
101                 return _peerInterfaceAddress;
102             }
103         }
104
105         /// <summary>
106         /// Listening channel of the peer device.
107         /// </summary>
108         public int Channel
109         {
110             get
111             {
112                 return _peerChannel;
113             }
114         }
115
116         /// <summary>
117         /// Connected state of the peer device.
118         /// </summary>
119         public bool IsConnected
120         {
121             get
122             {
123                 return _isPeerConnected;
124             }
125         }
126
127         /// <summary>
128         /// P2P group state of the peer device.
129         /// </summary>
130         public bool IsGroupOwner
131         {
132             get
133             {
134                 return _isPeerGroupOwner;
135             }
136         }
137
138         /// <summary>
139         /// Persistent group state of the peer device.
140         /// </summary>
141         public bool IsPersistentGroupOwner
142         {
143             get
144             {
145                 return _isPeerPersistentGroupOwner;
146             }
147         }
148
149         /// <summary>
150         /// P2P state of the peer device.
151         /// </summary>
152         public bool P2PSupport
153         {
154             get
155             {
156                 return _peerP2PSupport;
157             }
158         }
159
160         /// <summary>
161         /// Primary catagory of the peer device.
162         /// </summary>
163         public WiFiDirectPrimaryDeviceType PrimaryType
164         {
165             get
166             {
167                 return _peerPrimaryType;
168             }
169         }
170
171         /// <summary>
172         /// Sub category of the peer device.
173         /// </summary>
174         public WiFiDirectSecondaryDeviceType SecondaryType
175         {
176             get
177             {
178                 return _peerSecondaryType;
179             }
180         }
181
182         /// <summary>
183         /// List of supported WPS type of the peer device.
184         /// </summary>
185         public int WpsTypes
186         {
187             get
188             {
189                 return _peerWpsTypes;
190             }
191         }
192
193         /// <summary>
194         /// P2P invitation state of the peer device.
195         /// </summary>
196         public bool IsP2PInvitationSupported
197         {
198             get
199             {
200                 return _p2PInvitationSupported;
201             }
202         }
203
204         /// <summary>
205         /// Number of registered services of the peer device.
206         /// </summary>
207         public uint ServiceCount
208         {
209             get
210             {
211                 return _peerServiceCount;
212             }
213         }
214
215         /// <summary>
216         /// List of registered services of the peer device.
217         /// </summary>
218         public IEnumerable<string> ServiceList
219         {
220             get
221             {
222                 return _peerServiceList;
223             }
224         }
225
226         /// <summary>
227         /// Checks if peer device is a wifi display device.
228         /// </summary>
229         public bool IsMiracastDevice
230         {
231             get
232             {
233                 return _isPeerMiracastDevice;
234             }
235         }
236
237         /// <summary>
238         /// Wi-Fi Display device type of the peer device.
239         /// </summary>
240         /// <remarks>
241         /// Wi-Fi Direct must be activated.
242         /// If there is any error, default value of WiFiDirectDisplayType will be returned.
243         /// </remarks>
244         public WiFiDirectDisplayType Display
245         {
246             get
247             {
248                 if (Globals.IsActivated)
249                 {
250                     WiFiDirectDisplayType displayType;
251                     int ret = Interop.WiFiDirect.GetDisplayType(_peerMacAddress, out displayType);
252                     if (ret != (int)WiFiDirectError.None)
253                     {
254                         Log.Error(Globals.LogTag, "Failed to get the peer display type, Error - " + (WiFiDirectError)ret);
255                     }
256
257                     return displayType;
258                 }
259
260                 else
261                 {
262                     return default(WiFiDirectDisplayType);
263                 }
264             }
265         }
266
267         /// <summary>
268         /// Wi-Fi Display Session Availability of the peer device.
269         /// </summary>
270         /// <remarks>
271         /// Wi-Fi Direct must be activated.
272         /// If there is any error, false will be returned.
273         /// </remarks>
274         public bool DisplayAvailability
275         {
276             get
277             {
278                 if (Globals.IsActivated)
279                 {
280                     bool displayAvailability;
281                     int ret = Interop.WiFiDirect.GetDisplayAvailability(_peerMacAddress, out displayAvailability);
282                     if (ret != (int)WiFiDirectError.None)
283                     {
284                         Log.Error(Globals.LogTag, "Failed to get the peer display availability, Error - " + (WiFiDirectError)ret);
285                     }
286
287                     return displayAvailability;
288                 }
289
290                 else
291                 {
292                     return false;
293                 }
294             }
295         }
296
297         /// <summary>
298         /// Hdcp information of the peer device.
299         /// </summary>
300         /// <remarks>
301         /// Wi-Fi Direct must be activated.
302         /// If there is any error, -1 will be returned.
303         /// </remarks>
304         public int Hdcp
305         {
306             get
307             {
308                 if (Globals.IsActivated)
309                 {
310                     int hdcpSupport;
311                     int ret = Interop.WiFiDirect.GetDisplayHdcp(_peerMacAddress, out hdcpSupport);
312                     if (ret != (int)WiFiDirectError.None)
313                     {
314                         Log.Error(Globals.LogTag, "Failed to get the peer display hdcp support, Error - " + (WiFiDirectError)ret);
315                         return -1;
316                     }
317
318                     return hdcpSupport;
319                 }
320
321                 else
322                 {
323                     return -1;
324                 }
325             }
326         }
327
328         /// <summary>
329         /// Port of the connected peer device.
330         /// </summary>
331         /// <remarks>
332         /// Wi-Fi Direct must be activated.
333         /// If there is any error, -1 will be returned.
334         /// </remarks>
335         public int Port
336         {
337             get
338             {
339                 if (Globals.IsActivated)
340                 {
341                     int displayPort;
342                     int ret = Interop.WiFiDirect.GetDisplayPort(_peerMacAddress, out displayPort);
343                     if (ret != (int)WiFiDirectError.None)
344                     {
345                         Log.Error(Globals.LogTag, "Failed to get the peer display port, Error - " + (WiFiDirectError)ret);
346                         return -1;
347                     }
348
349                     return displayPort;
350                 }
351
352                 else
353                 {
354                     return -1;
355                 }
356             }
357         }
358
359         /// <summary>
360         /// WiFi Display max throughput of the peer device.
361         /// </summary>
362         /// <remarks>
363         /// Wi-Fi Direct must be activated.
364         /// If there is any error, -1 will be returned.
365         /// </remarks>
366         public int Throughput
367         {
368             get
369             {
370                 if (Globals.IsActivated)
371                 {
372                     int displayThroughput;
373                     int ret = Interop.WiFiDirect.GetDisplayThroughput(_peerMacAddress, out displayThroughput);
374                     if (ret != (int)WiFiDirectError.None)
375                     {
376                         Log.Error(Globals.LogTag, "Failed to get the peer display max throughput, Error - " + (WiFiDirectError)ret);
377                         return -1;
378                     }
379
380                     return displayThroughput;
381                 }
382
383                 else
384                 {
385                     return -1;
386                 }
387             }
388         }
389
390         /// <summary>
391         /// (event) ConnectionStateChanged event is raised when the connection state of the peer device changes.
392         /// </summary>
393         public event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged
394         {
395             add
396             {
397                 if (Globals.IsInitialize)
398                 {
399                     if (_connectionStateChanged == null)
400                     {
401                         RegisterConnectionStateChangedEvent();
402                     }
403
404                     _connectionStateChanged += value;
405                 }
406             }
407
408             remove
409             {
410                 if (Globals.IsInitialize)
411                 {
412                     _connectionStateChanged -= value;
413                     if (_connectionStateChanged == null)
414                     {
415                         UnregisterConnectionStateChangedEvent();
416                     }
417                 }
418             }
419         }
420
421         /// <summary>
422         /// (event) IpAddressAssigned event is raised when ip address of the peer device is assigned.
423         /// </summary>
424         public event EventHandler<IpAddressAssignedEventArgs> IpAddressAssigned
425         {
426             add
427             {
428                 if (Globals.IsInitialize)
429                 {
430                     if (_ipAddressAssigned == null)
431                     {
432                         RegisterIpAddressAssignedEvent();
433                     }
434
435                     _ipAddressAssigned += value;
436                 }
437             }
438
439             remove
440             {
441                 if (Globals.IsInitialize)
442                 {
443                     _ipAddressAssigned -= value;
444                     if (_ipAddressAssigned == null)
445                     {
446                         UnregisterIpAddressAssignedEvent();
447                     }
448                 }
449             }
450         }
451
452         /// <summary>
453         /// (event) ServiceStateChanged is raised when state of service discovery is changed.
454         /// </summary>
455         public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
456         {
457             add
458             {
459                 if (Globals.IsInitialize)
460                 {
461                     if (_serviceStateChanged == null)
462                     {
463                         RegisterServiceStateChangedEvent();
464                     }
465
466                     _serviceStateChanged += value;
467                 }
468             }
469
470             remove
471             {
472                 if (Globals.IsInitialize)
473                 {
474                     _serviceStateChanged -= value;
475                     if (_serviceStateChanged == null)
476                     {
477                         UnregisterServiceStateChangedEvent();
478                     }
479                 }
480             }
481         }
482
483         private void RegisterConnectionStateChangedEvent()
484         {
485             _connectionStateChangedCallback = (int result, WiFiDirectConnectionState state, string address, IntPtr userData) =>
486             {
487                 if (_connectionStateChanged != null)
488                 {
489                     WiFiDirectError res = (WiFiDirectError)result;
490                     _connectionStateChanged(null, new ConnectionStateChangedEventArgs(res, state, address));
491                 }
492             };
493             int ret = Interop.WiFiDirect.SetConnectionChangedCallback(_connectionStateChangedCallback, IntPtr.Zero);
494             if (ret != (int)WiFiDirectError.None)
495             {
496                 Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (WiFiDirectError)ret);
497             }
498         }
499
500         private void UnregisterConnectionStateChangedEvent()
501         {
502             int ret = Interop.WiFiDirect.UnsetConnectionChangedCallback();
503             if (ret != (int)WiFiDirectError.None)
504             {
505                 Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (WiFiDirectError)ret);
506             }
507         }
508
509         private void RegisterIpAddressAssignedEvent()
510         {
511             _ipAddressAssignedCallback = (string macAddress, string ipAddress, string interfaceAddress, IntPtr userData) =>
512             {
513                 if (_ipAddressAssigned != null)
514                 {
515                     _ipAddressAssigned(null, new IpAddressAssignedEventArgs(macAddress, ipAddress, interfaceAddress));
516                 }
517             };
518             int ret = Interop.WiFiDirect.SetIpAddressAssignedCallback(_ipAddressAssignedCallback, IntPtr.Zero);
519             if (ret != (int)WiFiDirectError.None)
520             {
521                 Log.Error(Globals.LogTag, "Failed to set ip address assigned callback, Error - " + (WiFiDirectError)ret);
522             }
523         }
524
525         private void UnregisterIpAddressAssignedEvent()
526         {
527             int ret = Interop.WiFiDirect.UnsetIpAddressAssignedCallback();
528             if (ret != (int)WiFiDirectError.None)
529             {
530                 Log.Error(Globals.LogTag, "Failed to unset ip address assigned callback, Error - " + (WiFiDirectError)ret);
531             }
532         }
533
534         private void RegisterServiceStateChangedEvent()
535         {
536             _serviceStateChangedCallback = (int result, WiFiDirectServiceDiscoveryState stateInfo, WiFiDirectServiceType typeInfo, IntPtr responseData, string address, IntPtr userData) =>
537             {
538                 if (_serviceStateChanged != null)
539                 {
540                     WiFiDirectError error = (WiFiDirectError)result;
541                     WiFiDirectServiceDiscoveryState state = stateInfo;
542                     WiFiDirectServiceType type = typeInfo;
543                     string response = Marshal.PtrToStringAnsi(responseData);
544                     IntPtr peer;
545                     Interop.WiFiDirect.GetDiscoveredPeerInfo(address, out peer);
546                     DiscoveredPeerStruct peerStruct = (DiscoveredPeerStruct)Marshal.PtrToStructure(peer, typeof(DiscoveredPeerStruct));
547
548                     _serviceStateChanged(null, new ServiceStateChangedEventArgs(error, state, type, response, WiFiDirectUtils.ConvertStructToDiscoveredPeer(peerStruct)));
549                 }
550             };
551             int ret = Interop.WiFiDirect.SetServiceStateChangedCallback(_serviceStateChangedCallback, IntPtr.Zero);
552             if (ret != (int)WiFiDirectError.None)
553             {
554                 Log.Error(Globals.LogTag, "Failed to set service state changed callback, Error - " + (WiFiDirectError)ret);
555             }
556         }
557
558         private void UnregisterServiceStateChangedEvent()
559         {
560             int ret = Interop.WiFiDirect.UnsetServiceStateChangedCallback();
561             if (ret != (int)WiFiDirectError.None)
562             {
563                 Log.Error(Globals.LogTag, "Failed to unset service state changed callback, Error - " + (WiFiDirectError)ret);
564             }
565         }
566
567         /// <summary>
568         /// Connects to a specified remote device.
569         /// </summary>
570         /// <remarks>
571         /// Wi-Fi Direct must be activated.
572         /// If this succeeds, ConnectionStateChanged event will be invoked.
573         /// </remarks>
574         /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
575         public void Connect()
576         {
577             if (Globals.IsActivated)
578             {
579                 int ret = Interop.WiFiDirect.Connect(_peerMacAddress);
580                 if (ret != (int)WiFiDirectError.None)
581                 {
582                     Log.Error(Globals.LogTag, "Failed to connect, Error - " + (WiFiDirectError)ret);
583                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
584                 }
585             }
586
587             else
588             {
589                 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
590                 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
591             }
592         }
593
594         /// <summary>
595         /// Cancels the connection now in progress.
596         /// </summary>
597         /// <remarks>
598         /// Wi-Fi Direct must be activated.
599         /// </remarks>
600         /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
601         public void CancelConnection()
602         {
603             if (Globals.IsActivated)
604             {
605                 int ret = Interop.WiFiDirect.CancelConnection(_peerMacAddress);
606                 if (ret != (int)WiFiDirectError.None)
607                 {
608                     Log.Error(Globals.LogTag, "Failed to cancel the connection, Error - " + (WiFiDirectError)ret);
609                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
610                 }
611             }
612
613             else
614             {
615                 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
616                 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
617             }
618         }
619
620         /// <summary>
621         /// Disconnects the specified remote device.
622         /// </summary>
623         /// <remarks>
624         /// Wi-Fi Direct must be activated.
625         /// If this succeeds, ConnectionStateChanged event will be invoked.
626         /// </remarks>
627         /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
628         public void Disconnect()
629         {
630             if (Globals.IsActivated)
631             {
632                 int ret = Interop.WiFiDirect.Disconnect(_peerMacAddress);
633                 if (ret != (int)WiFiDirectError.None)
634                 {
635                     Log.Error(Globals.LogTag, "Failed to disconnect, Error - " + (WiFiDirectError)ret);
636                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
637                 }
638             }
639
640             else
641             {
642                 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
643                 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
644             }
645         }
646
647         /// <summary>
648         /// Allows a device to connect automatically.
649         /// </summary>
650         /// <remarks>
651         /// Wi-Fi Direct must be activated.
652         /// </remarks>
653         /// <exception cref="NotSupportedException">Thrown when the wifidirect is not supported</exception>
654         public void SetAutoConnect()
655         {
656             if (Globals.IsActivated)
657             {
658                 int ret = Interop.WiFiDirect.SetAutoConnectionPeer(_peerMacAddress);
659                 if (ret != (int)WiFiDirectError.None)
660                 {
661                     Log.Error(Globals.LogTag, "Failed to set auto connection, Error - " + (WiFiDirectError)ret);
662                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
663                 }
664             }
665
666             else
667             {
668                 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
669                 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
670             }
671         }
672
673         /// <summary>
674         /// Starts the Wi-Fi Direct service discovery.
675         /// </summary>
676         /// <remarks>
677         /// Wi-Fi Direct must be activated.
678         /// If this succeeds, ServiceStateChanged event will be invoked.
679         /// </remarks>
680         /// <exception cref="NotSupportedException">
681         /// Thrown during one of the following cases :
682         /// 1. When the wifidirect is not supported
683         /// 2. When the wifidirect service discovery is not supported
684         /// </exception>
685         /// <param name="type">Type of service.</param>
686         public void StartServiceDiscovery(WiFiDirectServiceType type)
687         {
688             if (Globals.IsActivated)
689             {
690                 int ret = Interop.WiFiDirect.StartServiceDiscovery(_peerMacAddress, type);
691                 if (ret != (int)WiFiDirectError.None)
692                 {
693                     Log.Error(Globals.LogTag, "Failed to start Wi-Fi Direct service discovery, Error - " + (WiFiDirectError)ret);
694                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
695                 }
696             }
697
698             else
699             {
700                 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
701                 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
702             }
703         }
704
705         /// <summary>
706         /// Stops the Wi-Fi Direct service discovery.
707         /// </summary>
708         /// <remarks>
709         /// Wi-Fi Direct must be activated.
710         /// </remarks>
711         /// <exception cref="NotSupportedException">
712         /// Thrown during one of the following cases :
713         /// 1. When the wifidirect is not supported
714         /// 2. When the wifidirect service discovery is not supported
715         /// </exception>
716         /// <param name="type">Type of service.</param>
717         public void CancelServiceDiscovery(WiFiDirectServiceType type)
718         {
719             if (Globals.IsActivated)
720             {
721                 int ret = Interop.WiFiDirect.StopServiceDiscovery(_peerMacAddress, type);
722                 if (ret != (int)WiFiDirectError.None)
723                 {
724                     Log.Error(Globals.LogTag, "Failed to stop Wi-Fi Direct service discovery, Error - " + (WiFiDirectError)ret);
725                     WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
726                 }
727             }
728
729             else
730             {
731                 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
732                 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
733             }
734         }
735     }
736 }