2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
24 namespace Tizen.Network.WiFiDirect
27 /// The WiFiDirectPeer class is used to handle the connection with remote devices using Wi-Fi Direct.
29 /// <privilege> http://tizen.org/privilege/wifidirect </privilege>
30 public class WiFiDirectPeer
32 private event EventHandler<ConnectionStateChangedEventArgs> _connectionStateChanged;
33 private event EventHandler<IpAddressAssignedEventArgs> _ipAddressAssigned;
34 private event EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
36 private Interop.WiFiDirect.ConnectionStateChangedCallback _connectionStateChangedCallback;
37 private Interop.WiFiDirect.ClientIpAddressAssignedCallback _ipAddressAssignedCallback;
38 private Interop.WiFiDirect.ServiceStateChangedCallback _serviceStateChangedCallback;
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;
56 internal WiFiDirectPeer()
61 /// The name of the peer device.
67 return _peerDeviceName;
72 /// The IP address of the peer device.
74 public string IpAddress
78 return _peerIpAddress;
83 /// The MAC address of the peer device.
85 public string MacAddress
89 return _peerMacAddress;
94 /// The Interface address of the peer device.
96 public string InterfaceAddress
100 return _peerInterfaceAddress;
105 /// The listening channel of the peer device.
116 /// The connected state of the peer device.
118 public bool IsConnected
122 return _isPeerConnected;
127 /// The P2P group state of the peer device.
129 public bool IsGroupOwner
133 return _isPeerGroupOwner;
138 /// The P2P state of the peer device.
140 public bool P2PSupport
144 return _peerP2PSupport;
149 /// The primary catagory of the peer device.
151 public WiFiDirectPrimaryDeviceType PrimaryType
155 return _peerPrimaryType;
160 /// The sub category of the peer device.
162 public WiFiDirectSecondaryDeviceType SecondaryType
166 return _peerSecondaryType;
171 /// The list of the supported WPS type of the peer device.
177 return _peerWpsTypes;
182 /// The P2P invitation state of the peer device.
184 public bool IsP2PInvitationSupported
188 return _p2PInvitationSupported;
193 /// The number of registered services of the peer device.
195 public uint ServiceCount
199 return _peerServiceCount;
204 /// The list of registered services of the peer device.
206 public IEnumerable<string> ServiceList
210 return _peerServiceList;
215 /// Checks if the peer device is a Wi-Fi display device.
217 public bool IsMiracastDevice
221 return _isPeerMiracastDevice;
226 /// The Wi-Fi display device type of the peer device.
229 /// Wi-Fi Direct must be activated.
230 /// If there is any error, a default value of WiFiDirectDisplayType will be returned.
232 public WiFiDirectDisplayType Display
236 if (Globals.IsActivated)
238 WiFiDirectDisplayType displayType;
239 int ret = Interop.WiFiDirect.GetDisplayType(_peerMacAddress, out displayType);
240 if (ret != (int)WiFiDirectError.None)
242 Log.Error(Globals.LogTag, "Failed to get the peer display type, Error - " + (WiFiDirectError)ret);
250 return default(WiFiDirectDisplayType);
256 /// The Wi-Fi display session availability of the peer device.
259 /// Wi-Fi Direct must be activated.
260 /// If there is any error, false will be returned.
262 public bool DisplayAvailability
266 if (Globals.IsActivated)
268 bool displayAvailability;
269 int ret = Interop.WiFiDirect.GetDisplayAvailability(_peerMacAddress, out displayAvailability);
270 if (ret != (int)WiFiDirectError.None)
272 Log.Error(Globals.LogTag, "Failed to get the peer display availability, Error - " + (WiFiDirectError)ret);
275 return displayAvailability;
286 /// The HDCP information of the peer device.
289 /// Wi-Fi Direct must be activated.
290 /// If there is any error, -1 will be returned.
296 if (Globals.IsActivated)
299 int ret = Interop.WiFiDirect.GetDisplayHdcp(_peerMacAddress, out hdcpSupport);
300 if (ret != (int)WiFiDirectError.None)
302 Log.Error(Globals.LogTag, "Failed to get the peer display hdcp support, Error - " + (WiFiDirectError)ret);
317 /// The port of the connected peer device.
320 /// Wi-Fi Direct must be activated.
321 /// If there is any error, -1 will be returned.
327 if (Globals.IsActivated)
330 int ret = Interop.WiFiDirect.GetDisplayPort(_peerMacAddress, out displayPort);
331 if (ret != (int)WiFiDirectError.None)
333 Log.Error(Globals.LogTag, "Failed to get the peer display port, Error - " + (WiFiDirectError)ret);
348 /// The Wi-Fi display maximum throughput of the peer device.
351 /// Wi-Fi Direct must be activated.
352 /// If there is any error, -1 will be returned.
354 public int Throughput
358 if (Globals.IsActivated)
360 int displayThroughput;
361 int ret = Interop.WiFiDirect.GetDisplayThroughput(_peerMacAddress, out displayThroughput);
362 if (ret != (int)WiFiDirectError.None)
364 Log.Error(Globals.LogTag, "Failed to get the peer display max throughput, Error - " + (WiFiDirectError)ret);
368 return displayThroughput;
379 /// The Wi-Fi RSSI value of the peer device.
382 /// Wi-Fi Direct must be activated.
383 /// If there is any error, -1 will be returned.
389 if (Globals.IsActivated)
392 int ret = Interop.WiFiDirect.GetRssi(_peerMacAddress, out rssi);
393 if (ret != (int)WiFiDirectError.None)
395 Log.Error(Globals.LogTag, "Failed to get the peer RSSI, Error - " + (WiFiDirectError)ret);
409 /// The ConnectionStateChanged event is raised when the connection state of the peer device changes.
411 public event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged
415 if (Globals.IsInitialize)
417 if (_connectionStateChanged == null)
419 RegisterConnectionStateChangedEvent();
422 _connectionStateChanged += value;
428 if (Globals.IsInitialize)
430 _connectionStateChanged -= value;
431 if (_connectionStateChanged == null)
433 UnregisterConnectionStateChangedEvent();
440 /// The IpAddressAssigned event is raised when the IP address of the peer device is assigned.
442 public event EventHandler<IpAddressAssignedEventArgs> IpAddressAssigned
446 if (Globals.IsInitialize)
448 if (_ipAddressAssigned == null)
450 RegisterIpAddressAssignedEvent();
453 _ipAddressAssigned += value;
459 if (Globals.IsInitialize)
461 _ipAddressAssigned -= value;
462 if (_ipAddressAssigned == null)
464 UnregisterIpAddressAssignedEvent();
471 /// The ServiceStateChanged event is raised when the state of service discovery is changed.
473 public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
477 if (Globals.IsInitialize)
479 if (_serviceStateChanged == null)
481 RegisterServiceStateChangedEvent();
484 _serviceStateChanged += value;
490 if (Globals.IsInitialize)
492 _serviceStateChanged -= value;
493 if (_serviceStateChanged == null)
495 UnregisterServiceStateChangedEvent();
501 private void RegisterConnectionStateChangedEvent()
503 _connectionStateChangedCallback = (int result, WiFiDirectConnectionState state, string address, IntPtr userData) =>
505 if (_connectionStateChanged != null)
507 WiFiDirectError res = (WiFiDirectError)result;
508 _connectionStateChanged(null, new ConnectionStateChangedEventArgs(res, state, address));
511 int ret = Interop.WiFiDirect.SetConnectionChangedCallback(_connectionStateChangedCallback, IntPtr.Zero);
512 if (ret != (int)WiFiDirectError.None)
514 Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (WiFiDirectError)ret);
518 private void UnregisterConnectionStateChangedEvent()
520 int ret = Interop.WiFiDirect.UnsetConnectionChangedCallback();
521 if (ret != (int)WiFiDirectError.None)
523 Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (WiFiDirectError)ret);
527 private void RegisterIpAddressAssignedEvent()
529 _ipAddressAssignedCallback = (string macAddress, string ipAddress, string interfaceAddress, IntPtr userData) =>
531 if (_ipAddressAssigned != null)
533 _ipAddressAssigned(null, new IpAddressAssignedEventArgs(macAddress, ipAddress, interfaceAddress));
536 int ret = Interop.WiFiDirect.SetIpAddressAssignedCallback(_ipAddressAssignedCallback, IntPtr.Zero);
537 if (ret != (int)WiFiDirectError.None)
539 Log.Error(Globals.LogTag, "Failed to set ip address assigned callback, Error - " + (WiFiDirectError)ret);
543 private void UnregisterIpAddressAssignedEvent()
545 int ret = Interop.WiFiDirect.UnsetIpAddressAssignedCallback();
546 if (ret != (int)WiFiDirectError.None)
548 Log.Error(Globals.LogTag, "Failed to unset ip address assigned callback, Error - " + (WiFiDirectError)ret);
552 private void RegisterServiceStateChangedEvent()
554 _serviceStateChangedCallback = (int result, WiFiDirectServiceDiscoveryState stateInfo, WiFiDirectServiceType typeInfo, IntPtr responseData, string address, IntPtr userData) =>
556 if (_serviceStateChanged != null)
558 WiFiDirectError error = (WiFiDirectError)result;
559 WiFiDirectServiceDiscoveryState state = stateInfo;
560 WiFiDirectServiceType type = typeInfo;
561 string response = Marshal.PtrToStringAnsi(responseData);
563 Interop.WiFiDirect.GetDiscoveredPeerInfo(address, out peer);
564 DiscoveredPeerStruct peerStruct = (DiscoveredPeerStruct)Marshal.PtrToStructure(peer, typeof(DiscoveredPeerStruct));
566 _serviceStateChanged(null, new ServiceStateChangedEventArgs(error, state, type, response, WiFiDirectUtils.ConvertStructToDiscoveredPeer(peerStruct)));
569 int ret = Interop.WiFiDirect.SetServiceStateChangedCallback(_serviceStateChangedCallback, IntPtr.Zero);
570 if (ret != (int)WiFiDirectError.None)
572 Log.Error(Globals.LogTag, "Failed to set service state changed callback, Error - " + (WiFiDirectError)ret);
576 private void UnregisterServiceStateChangedEvent()
578 int ret = Interop.WiFiDirect.UnsetServiceStateChangedCallback();
579 if (ret != (int)WiFiDirectError.None)
581 Log.Error(Globals.LogTag, "Failed to unset service state changed callback, Error - " + (WiFiDirectError)ret);
586 /// Connects to a specified remote device.
589 /// Wi-Fi Direct must be activated.
590 /// If this succeeds, the ConnectionStateChanged event will be invoked.
592 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi Direct is not supported</exception>
593 public void Connect()
595 if (Globals.IsActivated)
597 int ret = Interop.WiFiDirect.Connect(_peerMacAddress);
598 if (ret != (int)WiFiDirectError.None)
600 Log.Error(Globals.LogTag, "Failed to connect, Error - " + (WiFiDirectError)ret);
601 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
607 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
608 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
613 /// Cancels the connection now in progress.
616 /// Wi-Fi Direct must be activated.
618 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi Direct is not supported.</exception>
619 public void CancelConnection()
621 if (Globals.IsActivated)
623 int ret = Interop.WiFiDirect.CancelConnection(_peerMacAddress);
624 if (ret != (int)WiFiDirectError.None)
626 Log.Error(Globals.LogTag, "Failed to cancel the connection, Error - " + (WiFiDirectError)ret);
627 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
633 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
634 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
639 /// Disconnects the specified remote device.
642 /// Wi-Fi Direct must be activated.
643 /// If this succeeds, the ConnectionStateChanged event will be invoked.
645 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi Direct is not supported.</exception>
646 public void Disconnect()
648 if (Globals.IsActivated)
650 int ret = Interop.WiFiDirect.Disconnect(_peerMacAddress);
651 if (ret != (int)WiFiDirectError.None)
653 Log.Error(Globals.LogTag, "Failed to disconnect, Error - " + (WiFiDirectError)ret);
654 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
660 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
661 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
666 /// Allows a device to connect automatically.
669 /// Wi-Fi Direct must be activated.
671 /// <exception cref="NotSupportedException">Thrown when the Wi-Fi Direct is not supported.</exception>
672 public void SetAutoConnect()
674 if (Globals.IsActivated)
676 int ret = Interop.WiFiDirect.SetAutoConnectionPeer(_peerMacAddress);
677 if (ret != (int)WiFiDirectError.None)
679 Log.Error(Globals.LogTag, "Failed to set auto connection, Error - " + (WiFiDirectError)ret);
680 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
686 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
687 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
692 /// Starts the Wi-Fi Direct service discovery.
695 /// Wi-Fi Direct must be activated.
696 /// If this succeeds, the ServiceStateChanged event will be invoked.
698 /// <exception cref="NotSupportedException">
699 /// Thrown during one of the following cases:
700 /// 1. When the Wi-Fi Direct is not supported.
701 /// 2. When the Wi-Fi Direct service discovery is not supported.
703 /// <param name="type">The type of the service.</param>
704 public void StartServiceDiscovery(WiFiDirectServiceType type)
706 if (Globals.IsActivated)
708 int ret = Interop.WiFiDirect.StartServiceDiscovery(_peerMacAddress, type);
709 if (ret != (int)WiFiDirectError.None)
711 Log.Error(Globals.LogTag, "Failed to start Wi-Fi Direct service discovery, Error - " + (WiFiDirectError)ret);
712 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
718 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
719 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);
724 /// Stops the Wi-Fi Direct service discovery.
727 /// Wi-Fi Direct must be activated.
729 /// <exception cref="NotSupportedException">
730 /// Thrown during one of the following cases:
731 /// 1. When the Wi-Fi Direct is not supported.
732 /// 2. When the Wi-Fi Direct service discovery is not supported.
734 /// <param name="type">The type of the service.</param>
735 public void CancelServiceDiscovery(WiFiDirectServiceType type)
737 if (Globals.IsActivated)
739 int ret = Interop.WiFiDirect.StopServiceDiscovery(_peerMacAddress, type);
740 if (ret != (int)WiFiDirectError.None)
742 Log.Error(Globals.LogTag, "Failed to stop Wi-Fi Direct service discovery, Error - " + (WiFiDirectError)ret);
743 WiFiDirectErrorFactory.ThrowWiFiDirectException(ret);
749 Log.Error(Globals.LogTag, "Wifi-direct is not activated");
750 WiFiDirectErrorFactory.ThrowWiFiDirectException((int)WiFiDirectError.NotPermitted);