Skip to content

Instantly share code, notes, and snippets.

@mikaelhg
Last active August 7, 2023 09:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikaelhg/ea41d5a117525d2af1aab5c8a3ec4dfb to your computer and use it in GitHub Desktop.
Save mikaelhg/ea41d5a117525d2af1aab5c8a3ec4dfb to your computer and use it in GitHub Desktop.
rtw89 CTRL-EVENT-BEACON-LOSS workaround
#!/bin/env python
# journalctl -u wpa_supplicant -f -o json | python event_listener.py
import json
import sys
import subprocess
__BEACON_LOSS = 'CTRL-EVENT-BEACON-LOSS'
__REASSOCIATE = ['/usr/bin/sudo', '/usr/sbin/wpa_cli', 'reassociate']
__WINDOW = 10 * 1_000_000
__THRESHOLD = 5
def main():
messages = []
for line in sys.stdin:
msg = json.loads(line)
print(msg['SYSLOG_TIMESTAMP'], msg['MESSAGE'])
messages.insert(0, msg)
if len(messages) > 100:
messages.pop()
t0 = int(msg['__REALTIME_TIMESTAMP'])
tc = t0 - __WINDOW
if __BEACON_LOSS in msg['MESSAGE']:
error_count = 1
for h in messages:
if __BEACON_LOSS in h['MESSAGE']:
error_count += 1
if int(h['__REALTIME_TIMESTAMP']) < tc:
break
if error_count > __THRESHOLD:
print(f'more than {__THRESHOLD} in {__WINDOW}, reassociating...')
cp = subprocess.run(__REASSOCIATE)
print(f'Reassociate succeeded: {cp.returncode == 0}')
if __name__ == '__main__':
main()
#!/bin/env python
import socket
import sys
import os
import select
import time
__SOCKET = '/var/run/wpa_supplicant/wlp1s0'
__RECV_BUFFER_SIZE = 4096
__BEACON_LOSS = 'CTRL-EVENT-BEACON-LOSS'
__WINDOW = 20
__THRESHOLD = 10
def main():
try:
client_sockname = f'/tmp/wpa_ctrl_{os.getpid()}'
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind(client_sockname)
sock.connect(__SOCKET)
poll = select.poll()
poll.register(sock, select.POLLIN)
sock.send('ATTACH'.encode('utf-8'))
messages = []
while poll.poll():
msg = sock.recv(__RECV_BUFFER_SIZE).decode('utf-8')
t0 = time.monotonic()
tc = t0 - __WINDOW
messages.insert(0, (t0, msg))
if len(messages) > 100:
messages.pop()
print(f'wpa_supplicant: {t0:.0f} {msg.strip()}')
if __BEACON_LOSS in msg:
error_count = 0
for t, e in messages:
if __BEACON_LOSS in e:
error_count += 1
if t < tc:
break
if error_count > __THRESHOLD:
print(f'more than {__THRESHOLD} in {__WINDOW}, reassociating...')
sock.send('REASSOCIATE'.encode('utf-8'))
except (socket.error, KeyboardInterrupt) as msg:
print(msg)
sock.send('DEATTACH'.encode('utf-8'))
sock.close()
os.remove(client_sockname)
sys.exit(1)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment