Wifi.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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, bool wifiScan)
  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. if (wifiScan)
  40. {
  41. wlanInterface.Scan();//会影响网络
  42. }
  43. WlanAvailableNetwork[] rawNetworks = wlanInterface.GetAvailableNetworkList(WlanGetAvailableNetworkFlags.IncludeAllAdhocProfiles);
  44. List<WlanAvailableNetwork> networks = new List<WlanAvailableNetwork>();
  45. // Remove network entries without profile name if one exist with a profile name.
  46. foreach (WlanAvailableNetwork network in rawNetworks)
  47. {
  48. //屏蔽特殊wifi
  49. if (CheckAvailableSSID(network.dot11Ssid) == false)
  50. {
  51. continue;
  52. }
  53. bool hasProfileName = !string.IsNullOrEmpty(network.profileName);
  54. bool anotherInstanceWithProfileExists = rawNetworks.Where(n => n.Equals(network) && !string.IsNullOrEmpty(n.profileName)).Any();
  55. if (!anotherInstanceWithProfileExists || hasProfileName)
  56. networks.Add(network);
  57. }
  58. foreach (WlanAvailableNetwork network in networks)
  59. {
  60. accessPoints.Add(new AccessPoint(wlanInterface, network));
  61. }
  62. return accessPoints;
  63. }
  64. /// <summary>
  65. /// Disconnect all wifi interfaces
  66. /// </summary>
  67. public void Disconnect()
  68. {
  69. if (_client.NoWifiAvailable)
  70. return;
  71. foreach (WlanInterface wlanIface in _client.Interfaces)
  72. {
  73. wlanIface.Disconnect();
  74. }
  75. }
  76. public WifiStatus ConnectionStatus
  77. {
  78. get
  79. {
  80. if (!_isConnectionStatusSet)
  81. ConnectionStatus = GetForcedConnectionStatus();
  82. return _connectionStatus;
  83. }
  84. private set
  85. {
  86. _isConnectionStatusSet = true;
  87. _connectionStatus = value;
  88. }
  89. }
  90. private void inte_WlanNotification(WlanNotificationData notifyData)
  91. {
  92. if (notifyData.notificationSource == WlanNotificationSource.ACM && (NotifCodeACM)notifyData.NotificationCode == NotifCodeACM.Disconnected)
  93. OnConnectionStatusChanged(WifiStatus.Disconnected);
  94. else if (notifyData.notificationSource == WlanNotificationSource.MSM && (NotifCodeMSM)notifyData.NotificationCode == NotifCodeMSM.Connected)
  95. OnConnectionStatusChanged(WifiStatus.Connected);
  96. }
  97. private void OnConnectionStatusChanged(WifiStatus newStatus)
  98. {
  99. ConnectionStatus = newStatus;
  100. if (ConnectionStatusChanged != null)
  101. ConnectionStatusChanged(this, new WifiStatusEventArgs(newStatus));
  102. }
  103. // I don't like this method, it's slow, ugly and should be refactored ASAP.
  104. private WifiStatus GetForcedConnectionStatus()
  105. {
  106. if (NoWifiAvailable)
  107. return WifiStatus.Disconnected;
  108. bool connected = false;
  109. foreach (var i in _client.Interfaces)
  110. {
  111. try
  112. {
  113. var a = i.CurrentConnection; // Current connection throws an exception if disconnected.
  114. connected = true;
  115. }
  116. catch { }
  117. }
  118. if (connected)
  119. return WifiStatus.Connected;
  120. else
  121. return WifiStatus.Disconnected;
  122. }
  123. private bool CheckAvailableSSID(Dot11Ssid ssid)
  124. {
  125. var len = ssid.SSIDLength;
  126. var bytes = ssid.SSID;
  127. for (int i = 0; i < len; i++)
  128. {
  129. if (bytes[i] != 0)
  130. {
  131. return true;
  132. }
  133. }
  134. return false;
  135. }
  136. }
  137. public class WifiStatusEventArgs : EventArgs
  138. {
  139. public WifiStatus NewStatus { get; private set; }
  140. internal WifiStatusEventArgs(WifiStatus status) : base()
  141. {
  142. this.NewStatus = status;
  143. }
  144. }
  145. public enum WifiStatus
  146. {
  147. Disconnected,
  148. Connected
  149. }
  150. }