Wifi.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Vinno.FIS.Sonopost.Wireless.Win32;
  5. using Vinno.FIS.Sonopost.Wireless.Win32.Interop;
  6. using NotifCodeACM = Vinno.FIS.Sonopost.Wireless.Win32.Interop.WlanNotificationCodeAcm;
  7. using NotifCodeMSM = Vinno.FIS.Sonopost.Wireless.Win32.Interop.WlanNotificationCodeMsm;
  8. namespace Vinno.FIS.Sonopost.Wireless
  9. {
  10. public class Wifi
  11. {
  12. public event EventHandler<WifiStatusEventArgs> ConnectionStatusChanged;
  13. private WlanClient _client;
  14. private WifiStatus _connectionStatus;
  15. private bool _isConnectionStatusSet = false;
  16. public bool NoWifiAvailable = false;
  17. public Wifi()
  18. {
  19. _client = new WlanClient();
  20. NoWifiAvailable = _client.NoWifiAvailable;
  21. if (_client.NoWifiAvailable)
  22. return;
  23. foreach (var inte in _client.Interfaces)
  24. inte.WlanNotification += inte_WlanNotification;
  25. }
  26. /// <summary>
  27. /// Returns a list over all available access points
  28. /// </summary>
  29. public List<AccessPoint> GetAccessPoints(string id)
  30. {
  31. List<AccessPoint> accessPoints = new List<AccessPoint>();
  32. if (_client.NoWifiAvailable)
  33. return accessPoints;
  34. var wlanInterface = _client.Interfaces.FirstOrDefault(c => c.NetworkInterface.Id == id);
  35. if (wlanInterface == null)
  36. {
  37. return accessPoints;
  38. }
  39. wlanInterface.Scan();
  40. WlanAvailableNetwork[] rawNetworks = wlanInterface.GetAvailableNetworkList(WlanGetAvailableNetworkFlags.IncludeAllAdhocProfiles);
  41. List<WlanAvailableNetwork> networks = new List<WlanAvailableNetwork>();
  42. // Remove network entries without profile name if one exist with a profile name.
  43. foreach (WlanAvailableNetwork network in rawNetworks)
  44. {
  45. //屏蔽特殊wifi
  46. if (CheckAvailableSSID(network.dot11Ssid) == false)
  47. {
  48. continue;
  49. }
  50. bool hasProfileName = !string.IsNullOrEmpty(network.profileName);
  51. bool anotherInstanceWithProfileExists = rawNetworks.Where(n => n.Equals(network) && !string.IsNullOrEmpty(n.profileName)).Any();
  52. if (!anotherInstanceWithProfileExists || hasProfileName)
  53. networks.Add(network);
  54. }
  55. foreach (WlanAvailableNetwork network in networks)
  56. {
  57. accessPoints.Add(new AccessPoint(wlanInterface, network));
  58. }
  59. return accessPoints;
  60. }
  61. /// <summary>
  62. /// Disconnect all wifi interfaces
  63. /// </summary>
  64. public void Disconnect()
  65. {
  66. if (_client.NoWifiAvailable)
  67. return;
  68. foreach (WlanInterface wlanIface in _client.Interfaces)
  69. {
  70. wlanIface.Disconnect();
  71. }
  72. }
  73. public WifiStatus ConnectionStatus
  74. {
  75. get
  76. {
  77. if (!_isConnectionStatusSet)
  78. ConnectionStatus = GetForcedConnectionStatus();
  79. return _connectionStatus;
  80. }
  81. private set
  82. {
  83. _isConnectionStatusSet = true;
  84. _connectionStatus = value;
  85. }
  86. }
  87. private void inte_WlanNotification(WlanNotificationData notifyData)
  88. {
  89. if (notifyData.notificationSource == WlanNotificationSource.ACM && (NotifCodeACM)notifyData.NotificationCode == NotifCodeACM.Disconnected)
  90. OnConnectionStatusChanged(WifiStatus.Disconnected);
  91. else if (notifyData.notificationSource == WlanNotificationSource.MSM && (NotifCodeMSM)notifyData.NotificationCode == NotifCodeMSM.Connected)
  92. OnConnectionStatusChanged(WifiStatus.Connected);
  93. }
  94. private void OnConnectionStatusChanged(WifiStatus newStatus)
  95. {
  96. ConnectionStatus = newStatus;
  97. if (ConnectionStatusChanged != null)
  98. ConnectionStatusChanged(this, new WifiStatusEventArgs(newStatus));
  99. }
  100. // I don't like this method, it's slow, ugly and should be refactored ASAP.
  101. private WifiStatus GetForcedConnectionStatus()
  102. {
  103. if (NoWifiAvailable)
  104. return WifiStatus.Disconnected;
  105. bool connected = false;
  106. foreach (var i in _client.Interfaces)
  107. {
  108. try
  109. {
  110. var a = i.CurrentConnection; // Current connection throws an exception if disconnected.
  111. connected = true;
  112. }
  113. catch { }
  114. }
  115. if (connected)
  116. return WifiStatus.Connected;
  117. else
  118. return WifiStatus.Disconnected;
  119. }
  120. private bool CheckAvailableSSID(Dot11Ssid ssid)
  121. {
  122. var len = ssid.SSIDLength;
  123. var bytes = ssid.SSID;
  124. for (int i = 0; i < len; i++)
  125. {
  126. if (bytes[i] != 0)
  127. {
  128. return true;
  129. }
  130. }
  131. return false;
  132. }
  133. }
  134. public class WifiStatusEventArgs : EventArgs
  135. {
  136. public WifiStatus NewStatus { get; private set; }
  137. internal WifiStatusEventArgs(WifiStatus status) : base()
  138. {
  139. this.NewStatus = status;
  140. }
  141. }
  142. public enum WifiStatus
  143. {
  144. Disconnected,
  145. Connected
  146. }
  147. }