Hi,
I have had recent problems with a SqueezeBoxRadio that had been 100% reliable on a wifi link for several years and then suddenly started disconnecting and required either network repair, and more often reboot to get connectivity up again. I assumed it must have been new wifi interference out of my control. If I placed the unit directly in front of my AP. It did not happen, but when I placed it back into the position I wanted it (at some distance) it started with disconnects.
I noticed others in related posts had similar issues. So I worked on this a little. Hope someone else might find this useful....
During investigations, I tried with little success to use ssh on the client while this was happening and even tried saving logs to another file to try and capture what was occurring. It all proved ineffective. So finally I attached to the serial interface on the SqueezeBoxRadio and waited for disconnect.
It seems that when these disconnects occur it is not possible to simply restart the IP layer or for that matter the wpa_supplicant. Both are dependent on the the atheros wireless driver. This seems to have a bug that places it into a uni-directional state. Traffic out from the IP layer but responses do not make it to the host.
Therefore to avoid debugging the wireless code ???? I came up with a work around:
Essentially a simple ping based bidirectional forwarding detection mechanism, that regularly pings the squeeze server according to the info in the server config file, and if pings fail, it unloads the entire atheros driver, reloads again aquires a new IP and actually the higher layer (Squeezeplay) rides this out and the connection loss is invisible to the user application.
Nasty but effective. To kick off the script I modified /etc/network/udhcpc_action. This now starts an instance of my BFD.sh script every time a dhcp lease is acquired. It also looks for an instance of the script BFD.sh pid file, to ensure it does not attempt to start multiple instances each time a dhcp renew occurs. The BFD.sh script does a simple job of cleaning up its own pid files and runs continuously until a disconnect occurs. It then reloads the driver modules and then exits, waits for dhcp to acquire an IP address and is then restarted by udhcpc_action, only when IP connectivity should be re-established.
/etc/network/BFD.sh
modified /etc/network/udhcpc_action
I have had recent problems with a SqueezeBoxRadio that had been 100% reliable on a wifi link for several years and then suddenly started disconnecting and required either network repair, and more often reboot to get connectivity up again. I assumed it must have been new wifi interference out of my control. If I placed the unit directly in front of my AP. It did not happen, but when I placed it back into the position I wanted it (at some distance) it started with disconnects.
I noticed others in related posts had similar issues. So I worked on this a little. Hope someone else might find this useful....
During investigations, I tried with little success to use ssh on the client while this was happening and even tried saving logs to another file to try and capture what was occurring. It all proved ineffective. So finally I attached to the serial interface on the SqueezeBoxRadio and waited for disconnect.
It seems that when these disconnects occur it is not possible to simply restart the IP layer or for that matter the wpa_supplicant. Both are dependent on the the atheros wireless driver. This seems to have a bug that places it into a uni-directional state. Traffic out from the IP layer but responses do not make it to the host.
Therefore to avoid debugging the wireless code ???? I came up with a work around:
Essentially a simple ping based bidirectional forwarding detection mechanism, that regularly pings the squeeze server according to the info in the server config file, and if pings fail, it unloads the entire atheros driver, reloads again aquires a new IP and actually the higher layer (Squeezeplay) rides this out and the connection loss is invisible to the user application.
Nasty but effective. To kick off the script I modified /etc/network/udhcpc_action. This now starts an instance of my BFD.sh script every time a dhcp lease is acquired. It also looks for an instance of the script BFD.sh pid file, to ensure it does not attempt to start multiple instances each time a dhcp renew occurs. The BFD.sh script does a simple job of cleaning up its own pid files and runs continuously until a disconnect occurs. It then reloads the driver modules and then exits, waits for dhcp to acquire an IP address and is then restarted by udhcpc_action, only when IP connectivity should be re-established.
/etc/network/BFD.sh
Code:
#!/bin/sh loop="true" if test -f "/var/run/BFD.pid"; then for pr_num in $(pidof BFD.sh); do if [ $pr_num != $$ ]; then kill -9 $pr_num fi done rm /var/run/BFD.pid fi /usr/bin/logger "BFD Daemon started with PID: "$$ echo $$ > /var/run/BFD.pid server=$(awk -F"serverInit=" '{print $2}' /etc/squeezeplay/userpath/settings/Playback.lua | awk -F"," '{print $2}' | cut -d '"' -f2) while [ $loop == "true" ] do ping -W 1 -w 10 -c 5 $server > /dev/null if [ $? -ne 0 ]; then /usr/bin/logger "Ping Bidirectional Forwarding Detection failed: Restarting wlan." /etc/init.d/wlan stop sleep 2 /etc/init.d/wlan start rm /var/run/BFD.pid udhcpc -R -a -p /var/run/udhcpc.eth1.pid -b --syslog -i eth1 -H SqueezeboxRadio -s /etc/network/udhcpc_action #dropbear -i loop="false" else loop="true" fi sleep 5 done
Code:
#!/bin/sh # udhcpc script edited by Tim Riker <[email protected]> # zcip integration idea from here: http://osdir.com/ml/network.zeroconf.workers/2005-06/msg00000.html [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 RESOLV_CONF="/etc/resolv.conf" [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" [ -n "$subnet" ] && NETMASK="netmask $subnet" /usr/bin/logger "udhcpc_action $interface $1 ip=$ip" case "$1" in deconfig) killall zcip > /dev/null /sbin/ifconfig $interface 0.0.0.0 ;; fail|leasefail) killall zcip > /dev/null # -v is needed to work around a bug in zcip - probably fixed in newer version /sbin/zcip -v $interface /etc/network/zcip_action > /dev/null & ;; renew|bound|zeroconf) killall zcip > /dev/null /sbin/ifconfig $interface $ip $BROADCAST $NETMASK while route del default gw 0.0.0.0 dev $interface ; do : done if [ -n "$router" ] ; then metric=0 for i in $router ; do route add default gw $i dev $interface metric $metric metric=$metric+1 done else route add default dev $interface fi echo -n > $RESOLV_CONF [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF for i in $dns ; do echo adding dns $i echo nameserver $i >> $RESOLV_CONF done if [ ! -f "/var/run/BFD.pid" ]; then (/etc/network/BFD.sh &) & fi ;; esac exit 0
Comment