Skip to content

Commit

Permalink
This commit is a WIP to fix WiFi scan on MacOS
Browse files Browse the repository at this point in the history
This works toward solving gopro#506
  • Loading branch information
epheo committed Apr 8, 2024
1 parent 56aed48 commit a454161
Showing 1 changed file with 33 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -679,33 +679,47 @@ def connect(self, ssid: str, password: str, timeout: float = 15) -> bool:
Returns:
bool: [description]
"""

import objc
from CoreWLAN import CWInterface
from CoreLocation import CLLocationManager

# Escape single quotes
ssid = ssid.replace(r"'", '''"'"''')

This comment has been minimized.

Copy link
@epheo

epheo Apr 8, 2024

Author Owner

I'm unsure if this is still necessary, I experienced issues with WiFI AP containing quotes using airport -s


logger.info(f"Scanning for {ssid}...")
start = time.time()
discovered = False

while not discovered and (time.time() - start) <= timeout:
# Scan for network
# Surprisingly, yes this is the industry standard location for this and no, there's no shortcut for it
response = cmd(
r"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --scan"
)
# TODO Sometimes the response is blank?
if not response:
logger.warning("MacOS did not return a response to SSID scanning.")
continue
lines = response.splitlines()
ssid_end_index = lines[0].index("SSID") + 4 # Find where the SSID column ends

for result in lines[1:]: # Skip title row
current_ssid = result[:ssid_end_index].strip()
if current_ssid == ssid.strip():
discovered = True

# Grant Location Services as required to get SSID from CoreWLAN
location_manager = CLLocationManager.alloc().init()
location_manager.startUpdatingLocation()

# Load CoreWLAN framework
objc.loadBundle('CoreWLAN',
bundle_path='/System/Library/Frameworks/CoreWLAN.framework',
module_globals=globals())

# Create a CWInterface object
interface = CWInterface.interface()

# Scan for networks
error = None
networks, error = interface.scanForNetworksWithSSID_error_(None, None)

if error:
logger.error(f"Error scanning for Wi-Fi networks: {error}")
else:
for network in networks:
logger.debug(f"Scanned SSID: {network.ssid()}")
if ssid.strip() in network.ssid():
discovered = True
break
if discovered:
break
if discovered:
break
time.sleep(1)
time.sleep(1)
else:
logger.warning("Wifi Scan timed out")
return False
Expand Down

0 comments on commit a454161

Please sign in to comment.