Skip to content

Commit 9b05bd2

Browse files
committed
Refactor list_access_points
1 parent a598b5b commit 9b05bd2

File tree

2 files changed

+80
-58
lines changed

2 files changed

+80
-58
lines changed

src/common/errors.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class WifiInvalidConnectionType(Exception):
2828
pass
2929

3030

31+
class WifiNetworkManagerError(Exception):
32+
pass
33+
34+
3135
class WifiNoSuitableDevice(Exception):
3236
pass
3337

@@ -46,6 +50,10 @@ class WifiNoSuitableDevice(Exception):
4650
"message": "Invalid connection type.",
4751
"status": 500
4852
},
53+
"WifiNetworkManagerError": {
54+
"message": "Failed communicating with Network Manager.",
55+
"status": 500
56+
},
4957
"WifiNoSuitableDevice": {
5058
"message": "No suitable Wi-Fi device available.",
5159
"status": 404

src/common/wifi.py

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from common.errors import logger
77
from common.errors import WifiConnectionFailed
88
from common.errors import WifiHotspotStartFailed
9+
from common.errors import WifiNetworkManagerError
910
from common.errors import WifiNoSuitableDevice
1011
from common.nm_dicts import get_nm_dict
1112

@@ -15,6 +16,37 @@
1516
DBusGMainLoop(set_as_default=True)
1617

1718

19+
def analyse_access_point(ap):
20+
security = config.type_none
21+
22+
# Based on a subset of the AP_SEC flag settings
23+
# (https://developer.gnome.org/NetworkManager/1.2/nm-dbus-types.html#NM80211ApSecurityFlags)
24+
# to determine which type of security this AP uses.
25+
AP_SEC = NetworkManager.NM_802_11_AP_SEC_NONE
26+
if ap.Flags & NetworkManager.NM_802_11_AP_FLAGS_PRIVACY and \
27+
ap.WpaFlags == AP_SEC and \
28+
ap.RsnFlags == AP_SEC:
29+
security = config.type_wep
30+
31+
if ap.WpaFlags != AP_SEC:
32+
security = config.type_wpa
33+
34+
if ap.RsnFlags != AP_SEC:
35+
security = config.type_wpa2
36+
37+
if ap.WpaFlags & \
38+
NetworkManager.NM_802_11_AP_SEC_KEY_MGMT_802_1X or \
39+
ap.RsnFlags & \
40+
NetworkManager.NM_802_11_AP_SEC_KEY_MGMT_802_1X:
41+
security = config.type_enterprise
42+
43+
entry = {"ssid": ap.Ssid,
44+
"conn_type": security,
45+
"strength": int(ap.Strength)}
46+
47+
return entry
48+
49+
1850
def check_internet_status(host="8.8.8.8", port=53, timeout=5):
1951
try:
2052
socket.setdefaulttimeout(timeout)
@@ -53,10 +85,10 @@ def connect(conn_type=config.type_hotspot,
5385
if conn_type == config.type_hotspot and config.hotspot_password:
5486
password = config.hotspot_password
5587

56-
try:
57-
# Get the correct config based on type requested
58-
conn_dict = get_nm_dict(conn_type, ssid, username, password)
88+
# Get the correct config based on type requested
89+
conn_dict = get_nm_dict(conn_type, ssid, username, password)
5990

91+
try:
6092
NetworkManager.Settings.AddConnection(conn_dict)
6193
logger.info(f"Added connection of type {conn_type}")
6294

@@ -66,16 +98,14 @@ def connect(conn_type=config.type_hotspot,
6698
for x in NetworkManager.Settings.ListConnections()])
6799
conn = connections[config.ap_name]
68100

69-
# Find a suitable device
70-
ctype = conn.GetSettings()['connection']['type']
71-
dtype = {'802-11-wireless': NetworkManager.NM_DEVICE_TYPE_WIFI} \
72-
.get(ctype, ctype)
101+
# Save the wi-fi device object to a variable
102+
devices = dict([(x.DeviceType, x)
103+
for x in NetworkManager.NetworkManager.GetDevices()])
73104

74-
for dev in NetworkManager.NetworkManager.GetDevices():
75-
if dev.DeviceType == dtype:
76-
break
105+
if NetworkManager.NM_DEVICE_TYPE_WIFI in devices:
106+
dev = devices[NetworkManager.NM_DEVICE_TYPE_WIFI]
77107
else:
78-
logger.error(f"No suitable and available {ctype} device found")
108+
logger.error("No suitable and available device found")
79109
raise WifiNoSuitableDevice
80110

81111
# Connect
@@ -128,7 +158,7 @@ def forget(create_new_hotspot=False):
128158

129159
except Exception:
130160
logger.exception("Failed to delete network.")
131-
return False
161+
raise WifiNetworkManagerError
132162

133163
return True
134164

@@ -139,56 +169,40 @@ def list_access_points():
139169
# button will be disabled.
140170
iw_status = refresh_networks(retries=1)
141171

142-
ssids = [] # List to be returned
143-
144-
for dev in NetworkManager.NetworkManager.GetDevices():
145-
if dev.DeviceType != NetworkManager.NM_DEVICE_TYPE_WIFI:
146-
continue
147-
for ap in dev.GetAccessPoints():
148-
security = config.type_none
149-
150-
# Based on a subset of the AP_SEC flag settings
151-
# (https://developer.gnome.org/NetworkManager/1.2/nm-dbus-types.html#NM80211ApSecurityFlags)
152-
# determine which type of security this AP uses.
153-
AP_SEC = NetworkManager.NM_802_11_AP_SEC_NONE
154-
if ap.Flags & NetworkManager.NM_802_11_AP_FLAGS_PRIVACY and \
155-
ap.WpaFlags == AP_SEC and \
156-
ap.RsnFlags == AP_SEC:
157-
security = config.type_wep
158-
159-
if ap.WpaFlags != AP_SEC:
160-
security = config.type_wpa
161-
162-
if ap.RsnFlags != AP_SEC:
163-
security = config.type_wpa2
164-
165-
if ap.WpaFlags & \
166-
NetworkManager.NM_802_11_AP_SEC_KEY_MGMT_802_1X or \
167-
ap.RsnFlags & \
168-
NetworkManager.NM_802_11_AP_SEC_KEY_MGMT_802_1X:
169-
security = config.type_enterprise
170-
171-
entry = {"ssid": ap.Ssid,
172-
"conn_type": security,
173-
"strength": int(ap.Strength)}
174-
175-
# Do not add duplicates to the list
176-
if ssids.__contains__(entry):
177-
continue
178-
179-
# Do not add own hotspot to the list
180-
if ap.Ssid == config.hotspot_ssid:
181-
continue
172+
try:
173+
# Fetch dictionary of devices
174+
devices = dict([(x.DeviceType, x)
175+
for x in NetworkManager.NetworkManager.GetDevices()])
182176

183-
ssids.append(entry)
177+
# Save the wi-fi device object to a variable
178+
if NetworkManager.NM_DEVICE_TYPE_WIFI in devices:
179+
dev = devices[NetworkManager.NM_DEVICE_TYPE_WIFI]
180+
else:
181+
logger.error("No suitable and available device found")
182+
raise WifiNoSuitableDevice
184183

185-
# Sort SSIDs by signal strength
186-
ssids = sorted(ssids,
187-
key=lambda x: x['strength'],
188-
reverse=True)
184+
# For each wi-fi connection in range, identify it's details
185+
compiled_ssids = [analyse_access_point(ap)
186+
for ap in dev.GetAccessPoints()]
187+
except Exception:
188+
logger.exception('Failed listing access points.')
189+
raise WifiNetworkManagerError
190+
191+
# Sort SSIDs by signal strength
192+
compiled_ssids = sorted(compiled_ssids,
193+
key=lambda x: x['strength'],
194+
reverse=True)
195+
196+
# Remove duplicates and own hotspot from list.
197+
tmp = []
198+
ssids = []
199+
for item in compiled_ssids:
200+
if item['ssid'] not in tmp and item['ssid'] != config.hotspot_ssid:
201+
ssids.append(item)
202+
tmp.append(item['ssid'])
189203

190204
# Return a list of available SSIDs and their security type,
191-
# or [] for none available or error.
205+
# or [] for none available.
192206
return ssids, iw_status
193207

194208

0 commit comments

Comments
 (0)