barbieri-playground icon indicating copy to clipboard operation
barbieri-playground copied to clipboard

wifi-disconnect-low-signal evaluate other aspects of connection

Open gitthangbaby opened this issue 4 years ago • 3 comments

wifi-disconnect-low-signal looks robust. But on my OpenWrt, it will never trigger. There's no device having a specific SNR/dBm value, it's usually random between healthy and suffering devices. All of the time. What differs is RX/TX, time of last query, and number of packets:

CONNECTED_MAC  -71 dBm / -93 dBm (SNR 22)  0 ms ago
        RX: 52.0 MBit/s, MCS 5, 20MHz                 459825 Pkts.
        TX: 54.0 MBit/s                               292314 Pkts.
        expected throughput: unknown

DISCONNECTED_MAC  -62 dBm / -93 dBm (SNR 31)  6800 ms ago
        RX: 1.0 MBit/s                                     5 Pkts.
        TX: 54.0 MBit/s                                    3 Pkts.
        expected throughput: unknown

As you see, noise value doesn't matter. On the unhealthy frozen device, RX is just 1mbps, no packets, and query long time ago. In even worse case, RX is 0mbps, and additionally device won't get an IP. These 2 are the only cases where i need to kick out the device in order to make it reconnect. Sadly, it's not what i can do with the magic script published.

gitthangbaby avatar Feb 22 '21 10:02 gitthangbaby

having mwlwifi, it's hard but basic concept is:

IFS=$'\n'
while true; do
  for LINE in $(iwinfo wlanX assoclist | grep "ms ago"); do
    MAC=$(echo "$LINE" | awk '{ print $1 }')
    SIGNAL=$(echo "$LINE" | awk '{ print $2 }')
    QUERYTIME=$(echo "$LINE" | awk '{ print $9 }')

    if [ "$QUERYTIME" -ge "5000" ]; then
      sleep 5
      LINE=$(iwinfo wlanX assoclist | grep "ms ago" | grep $MAC)  #double check
      QUERYTIME=$(echo "$LINE" | awk '{ print $9 }')
      if [ "$QUERYTIME" -ge "2000" ]; then
        logger -t $0 WiFi "Device $MAC ($SIGNAL -dBm) is being reconnected..."
        ubus call hostapd.wlanX del_client "{'addr':'$MAC', 'reason':5, 'deauth':false, 'ban_time':0}" #iw dev wlanX station del $MAC
      fi
    fi
  done

  sleep 120 #slow
done

sometimes it needs to reset with 'wifi' command which might be added to the 3rd check. That reset could remove one random interface.. Thanks Marvell (WRT routers)!

gitthangbaby avatar Feb 22 '21 12:02 gitthangbaby

wifi-disconnect-low-signal looks robust. But on my OpenWrt, it will never trigger. There's no device having a specific SNR/dBm value, it's usually random between healthy and suffering devices. All of the time. What differs is RX/TX, time of last query, and number of packets:

CONNECTED_MAC  -71 dBm / -93 dBm (SNR 22)  0 ms ago
        RX: 52.0 MBit/s, MCS 5, 20MHz                 459825 Pkts.
        TX: 54.0 MBit/s                               292314 Pkts.
        expected throughput: unknown

DISCONNECTED_MAC  -62 dBm / -93 dBm (SNR 31)  6800 ms ago
        RX: 1.0 MBit/s                                     5 Pkts.
        TX: 54.0 MBit/s                                    3 Pkts.
        expected throughput: unknown

As you see, noise value doesn't matter. On the unhealthy frozen device, RX is just 1mbps, no packets, and query long time ago. In even worse case, RX is 0mbps, and additionally device won't get an IP. These 2 are the only cases where i need to kick out the device in order to make it reconnect. Sadly, it's not what i can do with the magic script published.

Well, this is not a real project, just some code I found in shell-script and I converted to lua so it's lighter on memory and simpler to run on the device... I published so it's easier for others to try, but I can't help you much. You can try to implement other logics instead of the signal-based calculations (but keep the current one as default, please) and I'll review and take the patch into the repository.

barbieri avatar Feb 22 '21 13:02 barbieri

having mwlwifi, it's hard but basic concept is:

IFS=$'\n'
while true; do
  for LINE in $(iwinfo wlanX assoclist | grep "ms ago"); do
    MAC=$(echo "$LINE" | awk '{ print $1 }')
    SIGNAL=$(echo "$LINE" | awk '{ print $2 }')
    QUERYTIME=$(echo "$LINE" | awk '{ print $9 }')

    if [ "$QUERYTIME" -ge "5000" ]; then
      sleep 5
      LINE=$(iwinfo wlanX assoclist | grep "ms ago" | grep $MAC)  #double check
      QUERYTIME=$(echo "$LINE" | awk '{ print $9 }')
      if [ "$QUERYTIME" -ge "2000" ]; then
        logger -t $0 WiFi "Device $MAC ($SIGNAL -dBm) is being reconnected..."
        ubus call hostapd.wlanX del_client "{'addr':'$MAC', 'reason':5, 'deauth':false, 'ban_time':0}" #iw dev wlanX station del $MAC
      fi
    fi
  done

  sleep 120 #slow
done

sometimes it needs to reset with 'wifi' command which might be added to the 3rd check. That reset could remove one random interface.. Thanks Marvell (WRT routers)!

if this does work reliably just convert this to lua (would be easier on systems resources than executing all of these shell commands, even with busybox), then add some configuration toggle to choose between the modes (or have the modes to co-exist) and I'll review and merge

barbieri avatar Feb 22 '21 13:02 barbieri