You are not logged in.
This is a script that implements automatic reconnect to WiFi access points. It's called hold-connect. It uses netcfg as backend, so any other connection types are also supported (like PPP link). It had been tested every day for 2 months with a buggy public wifi router (its DHCP server quite often failed).
Features:
- Checking of internet connection via host pinging with 1 packet;
- Reconnecting if link failure is detected;
- Informative output;
- Customizable hostname, check interval and retry count.
Dependencies:
- bash;
- netcfg 2.5.4;
- optional: configured sudo. To run from root, all "sudo" strings can be safely removed.
Syntax is simple: hold-connect netcfg_profile_name . Also some parameters can be customized inside script (follow comments). Therefore it's advised to keep script file somewhere like /home/user and place a symlink to it in /usr/bin.
Usage: start and enjoy! To stop it, simply kill it with ^C or kill -15.
hold-connect.sh:
#!/bin/bash
# hold-connect - simple script to hold wifi link up in hard conditions.
# Version: 060710
# USAGE:
#
# hold-connect profile_name
#
# Profile name is a valid netcfg profile used to reconnect.
#
# Return values:
# 0 - happens only when script runs more than infinite time :-)
# 1 - error in arguments
# 2 - error while connecting
# Adjustable constants are here:
TEST_URL="qrz.ru" # URL to check via pinging
CHECK_INTERVAL=30 # Network status checking interval, in seconds (default: 30)
RETRY_LIMIT=3 # Maximum number of retries (default: 3)
#
connect()
{
sudo netcfg down $CURRENT_PROFILE > /dev/null 2>&1
RETRY_COUNT=0
CONN_STAT="" # Trigger the cycle at start
while [ -z "`echo $CONN_STAT | grep DONE`" ]; do
if [ -n "$CONN_STAT" ]; then
echo "[`date +%H:%M:%S`] Failed to connect using $CURRENT_PROFILE, trying again"
fi
CONN_STAT="`sudo netcfg $CURRENT_PROFILE`"
if [ -n "`echo $CONN_STAT | grep "Association Failed"`" ]; then
if [ $RETRY_COUNT != $RETRY_LIMIT ]; then
echo "Access point unreachable"
RETRY_COUNT=$((RETRY_COUNT+1))
else
echo "More than $RETRY_LIMIT sequental errors, exiting"
exit 2
fi
else RETRY_COUNT=0; # reset if error is not sequental
fi
sleep 2
done
}
# Check if there's no parameters
if [ -z $1 ]; then
echo "hold-connect: no profile specified"
echo "Usage:"
echo " hold-connect profile_name"
exit 1
fi
# Check if profile exists
if [ -z `sudo netcfg -l | grep -x $1` ]; then
echo "hold-connect: profile $1 does not exist"
exit 1
fi
CURRENT_PROFILE=$1
echo "hold-connect 060710, using profile $CURRENT_PROFILE and test URL $TEST_URL"
while [ "1" ]; do
while [ -z "`ping -c 1 $TEST_URL 2> /dev/null`" ]; do # to be sure that netcfg isn't wrong
echo "No connect to $TEST_URL, raising $CURRENT_PROFILE"
connect
done
echo "[`date +%H:%M:%S`] *** Connection to $TEST_URL is up"
sleep $CHECK_INTERVAL
done
Offline
Thanks for sharing this beautiful script!
Offline
But it would be better if you would turn it into a daemon.
Offline
I cannot script but I made some minor change to your code and copied and modifyed the code ntpdate-daemon use. The result is a functional hold-connect daemon.
/usr/bin/hold-connect:
#!/bin/bash
# hold-connect - simple script to hold wifi link up in hard conditions.
# Version: 060710
# USAGE:
#
# hold-connect profile_name
#
# Profile name is a valid netcfg profile used to reconnect.
#
# Return values:
# 0 - happens only when script runs more than infinite time :-)
# 1 - error in arguments
# 2 - error while connecting
# Adjustable constants are here:
TEST_URL="qrz.ru" # URL to check via pinging
CHECK_INTERVAL=30 # Network status checking interval, in seconds (default: 30)
RETRY_LIMIT=3 # Maximum number of retries (default: 3)
CURRENT_PROFILE="korvmedmos" # Network profile to use
#
connect()
{
sudo netcfg down $CURRENT_PROFILE > /dev/null 2>&1
RETRY_COUNT=0
CONN_STAT="" # Trigger the cycle at start
while [ -z "`echo $CONN_STAT | grep DONE`" ]; do
if [ -n "$CONN_STAT" ]; then
echo "[`date +%H:%M:%S`] Failed to connect using $CURRENT_PROFILE, trying again" >> /var/log/hold-connect.log
fi
CONN_STAT="`sudo netcfg $CURRENT_PROFILE`"
if [ -n "`echo $CONN_STAT | grep "Association Failed"`" >> /var/log/hold-connect.log ]; then
if [ $RETRY_COUNT != $RETRY_LIMIT ]; then
echo "Access point unreachable" >> /var/log/hold-connect.log
RETRY_COUNT=$((RETRY_COUNT+1))
else
echo "More than $RETRY_LIMIT sequental errors, exiting" >> /var/log/hold-connect.log
exit 2
fi
else RETRY_COUNT=0; # reset if error is not sequental
fi
sleep 2
done
}
# Check if profile exists
if [ -z `sudo netcfg -l | grep -x $CURRENT_PROFILE` ]; then
echo "hold-connect: profile $1 does not exist" >> /var/log/hold-connect.log
exit 1
fi
echo "hold-connect 060710, using profile $CURRENT_PROFILE and test URL $TEST_URL" > /var/log/hold-connect.log
while [ "1" ]; do
while [ -z "`ping -c 1 $TEST_URL 2> /dev/null`" ]; do # to be sure that netcfg isn't wrong
echo "No connect to $TEST_URL, raising $CURRENT_PROFILE" >> /var/log/hold-connect.log
connect
done
echo "[`date +%H:%M:%S`] *** Connection to $TEST_URL is up" >> /var/log/hold-connect.log
sleep $CHECK_INTERVAL
done
/etc/rc.d/hold-connect:
#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
case "$1" in
start)
stat_busy "Starting hold-connect"
/usr/bin/hold-connect & > /dev/null 2>&1
if [ $? -gt 0 ]; then
stat_fail
else
add_daemon hold-connect
stat_done
fi
;;
stop)
stat_busy "Stopping hold-connect"
rm_daemon ntpdate
stat_done
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
Remove net-profiles and add hold-connect in /etc/rc.conf
Last edited by whacath (2010-09-16 16:54:11)
Offline
Ignore my above post. It is just plane stupid and you cant stop or restart the daemon.
Heres howit should look like:
/usr/bin/hold-connect:
#!/bin/bash
# hold-connect - simple script to hold wifi link up in hard conditions.
# Version: 060710
# USAGE:
#
# hold-connect profile_name
#
# Profile name is a valid netcfg profile used to reconnect.
#
# Return values:
# 0 - happens only when script runs more than infinite time :-)
# 1 - error in arguments
# 2 - error while connecting
# Adjustable constants are here:
TEST_URL="qrz.ru" # URL to check via pinging
CHECK_INTERVAL=30 # Network status checking interval, in seconds (default: 30)
RETRY_LIMIT=3 # Maximum number of retries (default: 3)
#
connect()
{
sudo netcfg down $CURRENT_PROFILE > /dev/null 2>&1
RETRY_COUNT=0
CONN_STAT="" # Trigger the cycle at start
while [ -z "`echo $CONN_STAT | grep DONE`" ]; do
if [ -n "$CONN_STAT" ]; then
echo "[`date +%H:%M:%S`] Failed to connect using $CURRENT_PROFILE, trying again" >> /var/log/hold-connect.log
fi
CONN_STAT="`sudo netcfg $CURRENT_PROFILE`"
if [ -n "`echo $CONN_STAT | grep "Association Failed"`" ]; then
if [ $RETRY_COUNT != $RETRY_LIMIT ]; then
echo "Access point unreachable" >> /var/log/hold-connect.log
RETRY_COUNT=$((RETRY_COUNT+1))
else
echo "More than $RETRY_LIMIT sequental errors, exiting" >> /var/log/hold-connect.log
exit 2
fi
else RETRY_COUNT=0; # reset if error is not sequental
fi
sleep 2
done
}
# Check if there's no parameters
if [ -z $1 ]; then
echo "hold-connect: no profile specified"
echo "Usage:"
echo " hold-connect profile_name"
exit 1
fi
# Check if profile exists
if [ -z `sudo netcfg -l | grep -x $1` ]; then
echo "hold-connect: profile $1 does not exist"
exit 1
fi
CURRENT_PROFILE=$1
echo "hold-connect 060710, using profile $CURRENT_PROFILE and test URL $TEST_URL" >> /var/log/hold-connect.log
while [ "1" ]; do
while [ -z "`ping -c 1 $TEST_URL 2> /dev/null`" ]; do # to be sure that netcfg isn't wrong
echo "No connect to $TEST_URL, raising $CURRENT_PROFILE" >> /var/log/hold-connect.log
connect
done
echo "[`date +%H:%M:%S`] *** Connection to $TEST_URL is up" >> /var/log/hold-connect.log
sleep $CHECK_INTERVAL
done
/etc/rc.d/hold-connect:
#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
CURRENT_PROFILE="korvmedmos" # Network profile to use
DIE=`ps alx | grep hold-connect | grep -v "grep" | awk '{ print $3 }'`
case "$1" in
start)
stat_busy "Starting hold-connect"
/usr/bin/hold-connect $CURRENT_PROFILE & > /dev/null 2>&1
if [ $? -gt 0 ]; then
stat_fail
else
add_daemon hold-connect
stat_done
fi
;;
stop)
stat_busy "Stopping hold-connect"
rm_daemon ntpdate
stat_done
kill $DIE
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
I need more brainzzz. Please give!
Last edited by whacath (2010-09-16 18:11:16)
Offline
Thanks for this, very helpful! We have a bit of a dodgy router that seems to sometimes just randomly kill the wifi connection. In order to resolve it the router needs to be restarted. (Yep useful...)
Anyway, I modified the script to remove the give-up-after-x-retries feature.
/usr/bin/hold-connect
#!/bin/bash
# hold-connect - simple script to hold wifi link up in hard conditions.
# Version: 060710
# USAGE:
#
# hold-connect profile_name
#
# Profile name is a valid netcfg profile used to reconnect.
#
# Return values:
# 0 - happens only when script runs more than infinite time :-)
# 1 - error in arguments
# 2 - error while connecting
# Adjustable constants are here:
TEST_URL="qrz.ru" # URL to check via pinging
CHECK_INTERVAL=30 # Network status checking interval, in seconds (default: 30)
#
connect()
{
sudo netcfg down $CURRENT_PROFILE > /dev/null 2>&1
RETRY_COUNT=0
CONN_STAT="" # Trigger the cycle at start
while [ -z "`echo $CONN_STAT | grep DONE`" ]; do
if [ -n "$CONN_STAT" ]; then
echo "[`date +%H:%M:%S`] Failed to connect using $CURRENT_PROFILE, trying again" >> /var/log/hold-connect.log
fi
CONN_STAT="`sudo netcfg $CURRENT_PROFILE`"
if [ -n "`echo $CONN_STAT | grep "Association Failed"`" ]; then
echo "Access point unreachable" >> /var/log/hold-connect.log
fi
sleep 2
done
}
# Check if there's no parameters
if [ -z $1 ]; then
echo "hold-connect: no profile specified"
echo "Usage:"
echo " hold-connect profile_name"
exit 1
fi
# Check if profile exists
if [ -z `sudo netcfg -l | grep -x $1` ]; then
echo "hold-connect: profile $1 does not exist"
exit 1
fi
CURRENT_PROFILE=$1
echo "hold-connect 060710, using profile $CURRENT_PROFILE and test URL $TEST_URL" >> /var/log/hold-connect.log
while [ "1" ]; do
while [ -z "`ping -c 1 $TEST_URL 2> /dev/null`" ]; do # to be sure that netcfg isn't wrong
echo "No connect to $TEST_URL, raising $CURRENT_PROFILE" >> /var/log/hold-connect.log
connect
done
echo "[`date +%H:%M:%S`] *** Connection to $TEST_URL is up" >> /var/log/hold-connect.log
sleep $CHECK_INTERVAL
done
Offline
I'm happy that the script was useful for anyone. But I wonder why you put ">> /var/log/hold_connect.log" to every "echo" command? IMO much less error-prone and easier to type "$ hold-connect some_profile >> /var/log/hold-connect.log".
Last edited by Kosmonavt (2011-01-24 21:41:51)
Offline