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