mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +01:00
auto-t: hostapd.py: use IO watch for hostapd events
With how fast UML is hostapd events were being sent out prior to ever calling wait_for_event. Instead set an IO watch on the control socket and cache all events as they come. Then, when wait_for_event is called, it can reference this list. If the event is found any older events are purged from the list. The AP-ENABLED event needed a special case because hostapd gets started before the IO watch can be registered. To fix this an enabled property was added which queries the state directly. This is checked first, and if not enabled wait_for_event continues normally.
This commit is contained in:
parent
dbd6ddfc95
commit
31b5275c1f
@ -81,27 +81,48 @@ class HostapdCLI(object):
|
|||||||
|
|
||||||
self.ctrl_sock.connect(self.socket_path + '/' + self.ifname)
|
self.ctrl_sock.connect(self.socket_path + '/' + self.ifname)
|
||||||
|
|
||||||
|
self.events = []
|
||||||
|
self.io_watch = GLib.io_add_watch(self.ctrl_sock, GLib.IO_IN, self._handle_data_in)
|
||||||
|
|
||||||
if 'OK' not in self._ctrl_request('ATTACH'):
|
if 'OK' not in self._ctrl_request('ATTACH'):
|
||||||
raise Exception('ATTACH failed')
|
raise Exception('ATTACH failed')
|
||||||
|
|
||||||
ctrl_count = ctrl_count + 1
|
ctrl_count = ctrl_count + 1
|
||||||
|
|
||||||
def _poll_event(self, event):
|
def _handle_data_in(self, sock, *args):
|
||||||
if not self._data_available(0.25):
|
newdata = sock.recv(4096)
|
||||||
return False
|
|
||||||
|
|
||||||
data = self.ctrl_sock.recv(4096).decode('utf-8')
|
decoded = newdata.decode('utf-8')
|
||||||
if event in data:
|
if len(decoded) >= 3 and decoded[0] == '<' and decoded[2] == '>':
|
||||||
return data
|
decoded = decoded[3:]
|
||||||
|
while len(decoded) and decoded[-1] == '\n':
|
||||||
|
decoded = decoded[:-1]
|
||||||
|
|
||||||
|
self.events.insert(0, decoded)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _poll_event(self, event):
|
||||||
|
# Look through the list (most recent is first) until the even is found.
|
||||||
|
# Once found consume this event and any older ones as to not
|
||||||
|
# accidentally trigger a false positive later on.
|
||||||
|
for idx, e in enumerate(self.events):
|
||||||
|
if event in e:
|
||||||
|
self.events = self.events[:idx]
|
||||||
|
return e
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def wait_for_event(self, event, timeout=10):
|
def wait_for_event(self, event, timeout=10):
|
||||||
|
if event == 'AP-ENABLED':
|
||||||
|
if self.enabled:
|
||||||
|
return 'AP-ENABLED'
|
||||||
|
|
||||||
return ctx.non_block_wait(self._poll_event, timeout, event,
|
return ctx.non_block_wait(self._poll_event, timeout, event,
|
||||||
exception=TimeoutError("waiting for event"))
|
exception=TimeoutError("waiting for event"))
|
||||||
|
|
||||||
def _data_available(self, timeout=2):
|
def _data_available(self):
|
||||||
[r, w, e] = select.select([self.ctrl_sock], [], [], timeout)
|
[r, w, e] = select.select([self.ctrl_sock], [], [])
|
||||||
if r:
|
if r:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@ -228,25 +249,28 @@ class HostapdCLI(object):
|
|||||||
ctx.start_process(cmd).wait()
|
ctx.start_process(cmd).wait()
|
||||||
self.wait_for_event('AP-CSA-FINISHED')
|
self.wait_for_event('AP-CSA-FINISHED')
|
||||||
|
|
||||||
@property
|
def _get_status(self):
|
||||||
def bssid(self):
|
ret = {}
|
||||||
|
|
||||||
cmd = self.cmdline + ['status']
|
cmd = self.cmdline + ['status']
|
||||||
proc = ctx.start_process(cmd)
|
proc = ctx.start_process(cmd)
|
||||||
proc.wait()
|
proc.wait()
|
||||||
status = proc.out.split('\n')
|
status = proc.out.strip().split('\n')
|
||||||
|
|
||||||
bssid = [x for x in status if x.startswith('bssid')]
|
for kv in status:
|
||||||
bssid = bssid[0].split('=')
|
k, v = kv.split('=')
|
||||||
return bssid[1]
|
ret[k] = v
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bssid(self):
|
||||||
|
return self._get_status()['bssid[0]']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def frequency(self):
|
def frequency(self):
|
||||||
cmd = self.cmdline + ['status']
|
return int(self._get_status()['freq'])
|
||||||
proc = ctx.start_process(cmd)
|
|
||||||
proc.wait()
|
|
||||||
status = proc.out.split('\n')
|
|
||||||
|
|
||||||
frequency = [x for x in status if x.startswith('freq')][0]
|
@property
|
||||||
frequency = frequency.split('=')[1]
|
def enabled(self):
|
||||||
|
return self._get_status()['state'] == 'ENABLED'
|
||||||
return int(frequency)
|
|
||||||
|
@ -540,7 +540,8 @@ class Hostapd:
|
|||||||
except:
|
except:
|
||||||
print("Failed to remove %s" % self.global_ctrl_iface)
|
print("Failed to remove %s" % self.global_ctrl_iface)
|
||||||
|
|
||||||
self.instances = None
|
for hapd in self.instances:
|
||||||
|
GLib.source_remove(hapd.cli.io_watch)
|
||||||
|
|
||||||
# Hostapd may have already been stopped
|
# Hostapd may have already been stopped
|
||||||
if self.process:
|
if self.process:
|
||||||
|
Loading…
Reference in New Issue
Block a user