Skip to content

Commit

Permalink
core: services: wifi: wpa_supplicant: Ensure that a single async oper…
Browse files Browse the repository at this point in the history
…ation will run for each command

Signed-off-by: Patrick José Pereira <[email protected]>
  • Loading branch information
patrickelectric committed Jul 5, 2024
1 parent 2871aab commit 3743630
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions core/services/wifi/wpa_supplicant.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import socket
import time
from pathlib import Path
from threading import Lock
from typing import Optional, Tuple, Union

from loguru import logger
Expand All @@ -17,6 +18,7 @@ class WPASupplicant:

def __init__(self) -> None:
self.sock: Optional[socket.socket] = None
self.lock = Lock()

def __del__(self) -> None:
if self.sock:
Expand Down Expand Up @@ -56,12 +58,15 @@ async def send_command(self, command: str, timeout: float) -> bytes:
timeout {float} -- Maximum time (in seconds) allowed for receiving an answer before raising a BusyError
"""
assert self.sock, "No socket assigned to WPA Supplicant"
# pylint: disable=consider-using-with
self.lock.acquire()

timeout_start = time.time()
while time.time() - timeout_start < timeout:
try:
self.sock.send(command.encode("utf-8"))
data, _ = self.sock.recvfrom(self.BUFFER_SIZE)
logger.debug(data)
except Exception as error:
# Oh my, something is wrong!
# For now, let us report the error but not without recreating the socket
Expand All @@ -73,6 +78,8 @@ async def send_command(self, command: str, timeout: float) -> bytes:
except Exception as inner_error:
logger.error(f"Failed to send command and failed to recreate wpa socket: {inner_error}")
raise SockCommError(error_message) from error
finally:
self.lock.release()

if b"FAIL-BUSY" in data:
logger.info(f"Busy during {command} operation. Trying again...")
Expand All @@ -84,8 +91,12 @@ async def send_command(self, command: str, timeout: float) -> bytes:
continue
break
else:
self.lock.release()
raise BusyError(f"{command} operation took more than specified timeout ({timeout}). Cancelling.")

if self.lock.locked():
self.lock.release()

if data == b"FAIL":
raise WPAOperationFail(f"WPA operation {command} failed.")

Expand Down

0 comments on commit 3743630

Please sign in to comment.