Skip to content

Commit e00a8c7

Browse files
committed
Prevent connection dropping on container restarts
1 parent c7463c9 commit e00a8c7

File tree

2 files changed

+50
-38
lines changed

2 files changed

+50
-38
lines changed

src/common/wifi.py

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ def auto_connect(ssid=None,
6666
connect()
6767

6868

69+
# Returns True when a connection to a router is made, or the Hotspot is live
70+
def check_device_state():
71+
# Save the wi-fi device object to a variable
72+
if get_device().State == NetworkManager.NM_DEVICE_STATE_ACTIVATED:
73+
return True
74+
else:
75+
return False
76+
77+
78+
# Ignores device and Wi-Fi status and checks for internet. Helpful for when
79+
# connected to Ethernet.
6980
def check_internet_status(host="8.8.8.8", port=53, timeout=5):
7081
try:
7182
socket.setdefaulttimeout(timeout)
@@ -77,6 +88,7 @@ def check_internet_status(host="8.8.8.8", port=53, timeout=5):
7788
return False
7889

7990

91+
# Checks if there is an active connection to an external Wi-Fi router
8092
def check_wifi_status():
8193
try:
8294
run = subprocess.run(["iw", "dev", "wlan0", "link"],
@@ -111,38 +123,27 @@ def connect(conn_type=config.type_hotspot,
111123
NetworkManager.Settings.AddConnection(conn_dict)
112124
logger.info(f"Adding connection of type {conn_type}")
113125

114-
# Find this connection and its device
115-
connections = \
116-
dict([(x.GetSettings()['connection']['id'], x)
117-
for x in NetworkManager.Settings.ListConnections()])
118-
conn = connections[config.ap_name]
119-
120126
# Save the wi-fi device object to a variable
121-
devices = dict([(x.DeviceType, x)
122-
for x in NetworkManager.NetworkManager.GetDevices()])
123-
124-
if NetworkManager.NM_DEVICE_TYPE_WIFI in devices:
125-
dev = devices[NetworkManager.NM_DEVICE_TYPE_WIFI]
126-
else:
127-
logger.error("No suitable and available device found")
128-
raise WifiNoSuitableDevice
127+
dev = get_device()
129128

130129
# Connect
131-
NetworkManager.NetworkManager.ActivateConnection(conn, dev, "/")
130+
NetworkManager.NetworkManager.ActivateConnection(get_connection_id(),
131+
dev,
132+
"/")
132133

133134
# If not a hotspot, log the connection SSID being attempted
134135
if conn_type != config.type_hotspot:
135136
logger.info(f"Attempting connection to {ssid}")
136137

137138
# Wait for ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
138139
loop_count = 0
139-
while dev.State != NetworkManager.NM_DEVICE_STATE_ACTIVATED:
140+
while not check_device_state():
140141
time.sleep(1)
141142
loop_count += 1
142143
if loop_count > 30: # Only wait 30 seconds max
143144
break
144145

145-
if dev.State == NetworkManager.NM_DEVICE_STATE_ACTIVATED:
146+
if check_device_state():
146147
logger.info("Connection active.")
147148

148149
# Activate the LED to indicate device is connected.
@@ -172,22 +173,18 @@ def connect(conn_type=config.type_hotspot,
172173
def forget(create_new_hotspot=False, all_networks=False):
173174
# Find and delete the hotspot connection
174175
try:
175-
connections = NetworkManager.Settings.ListConnections()
176-
177176
if all_networks:
178-
for connection in connections:
177+
for connection in NetworkManager.Settings.ListConnections():
179178
if connection.GetSettings()["connection"]["type"] \
180179
== "802-11-wireless":
181180
# Delete the identified connection
182181
network_id = connection.GetSettings()["connection"]["id"]
183182
connection.Delete()
184183
logger.debug(f"Deleted connection: {network_id}")
185184
else:
186-
connection_ids = \
187-
dict([(x.GetSettings()['connection']['id'], x)
188-
for x in connections])
189-
if config.ap_name in connection_ids:
190-
connection_ids[config.ap_name].Delete()
185+
connection_id = get_connection_id()
186+
if connection_id:
187+
connection_id.Delete()
191188
logger.debug(f"Deleted connection: {config.ap_name}")
192189

193190
# Disable LED indicating Wi-Fi is not active.
@@ -205,6 +202,27 @@ def forget(create_new_hotspot=False, all_networks=False):
205202
return True
206203

207204

205+
def get_connection_id():
206+
connection = dict([(x.GetSettings()['connection']['id'], x)
207+
for x in NetworkManager.Settings.ListConnections()])
208+
209+
if config.ap_name in connection:
210+
return connection[config.ap_name]
211+
else:
212+
return False
213+
214+
215+
def get_device():
216+
devices = dict([(x.DeviceType, x)
217+
for x in NetworkManager.NetworkManager.GetDevices()])
218+
219+
if NetworkManager.NM_DEVICE_TYPE_WIFI in devices:
220+
return devices[NetworkManager.NM_DEVICE_TYPE_WIFI]
221+
else:
222+
logger.error("No suitable or available device found.")
223+
raise WifiNoSuitableDevice
224+
225+
208226
def list_access_points():
209227
# Run IW to reduce chance of empty SSID list. Storing result
210228
# to return so that if IW does not work on this device the refresh
@@ -215,15 +233,7 @@ def list_access_points():
215233

216234
try:
217235
# Fetch dictionary of devices
218-
devices = dict([(x.DeviceType, x)
219-
for x in NetworkManager.NetworkManager.GetDevices()])
220-
221-
# Save the wi-fi device object to a variable
222-
if NetworkManager.NM_DEVICE_TYPE_WIFI in devices:
223-
dev = devices[NetworkManager.NM_DEVICE_TYPE_WIFI]
224-
else:
225-
logger.error("No suitable and available device found")
226-
raise WifiNoSuitableDevice
236+
dev = get_device()
227237

228238
# For each wi-fi connection in range, identify it's details
229239
compiled_ssids = [analyse_access_point(ap)
@@ -267,7 +277,7 @@ def refresh_networks(retries=5):
267277
time.sleep(3)
268278
subprocess.check_output(["iw", "dev", "wlan0", "scan"])
269279
except subprocess.CalledProcessError:
270-
logger.warning('Resource busy. Retrying...')
280+
logger.warning('IW resource busy. Retrying...')
271281
continue
272282
except Exception:
273283
logger.error('Unknown error calling IW.')

src/run.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from common.system import dnsmasq
66
from common.system import led
77
from common.wifi import auto_connect
8+
from common.wifi import check_device_state
89
from common.wifi import check_wifi_status
910
from common.wifi import connect
1011
from common.wifi import refresh_networks
@@ -45,11 +46,12 @@
4546
# Allow time for an exsiting saved Wi-Fi connection to connect.
4647
time.sleep(10)
4748

48-
# If the Wi-Fi connection is not already active, start a hotspot
49-
if check_wifi_status():
49+
# If the Wi-Fi connection or device is already active, do nothing
50+
if check_wifi_status() or check_device_state():
5051
led(1)
51-
logger.info('Wi-Fi connection already established.')
52+
logger.info('A Wi-Fi connection or hotspot is already active.')
5253
logger.info('Ready...')
54+
# If the Wi-Fi connection and device are not active, start a hotspot
5355
else:
5456
led(0)
5557
refresh_networks(retries=1)

0 commit comments

Comments
 (0)