You are not logged in.

#1 2010-08-19 10:11:38

Kosmonavt
Member
Registered: 2010-02-15
Posts: 100

Script to fight buggy WiFi access points

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

#2 2010-09-05 13:50:07

whacath
Member
Registered: 2009-05-26
Posts: 283

Re: Script to fight buggy WiFi access points

Thanks for sharing this beautiful script! smile

Offline

#3 2010-09-07 18:01:21

whacath
Member
Registered: 2009-05-26
Posts: 283

Re: Script to fight buggy WiFi access points

But it would be better if you would turn it into a daemon. smile

Offline

#4 2010-09-16 16:51:26

whacath
Member
Registered: 2009-05-26
Posts: 283

Re: Script to fight buggy WiFi access points

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. smile

/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

#5 2010-09-16 17:55:13

whacath
Member
Registered: 2009-05-26
Posts: 283

Re: Script to fight buggy WiFi access points

Ignore my above post. It is just plane stupid and you cant stop or restart  the daemon. tongue

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! hmm

Last edited by whacath (2010-09-16 18:11:16)

Offline

#6 2011-01-22 12:25:10

thelucster
Member
Registered: 2009-02-25
Posts: 24

Re: Script to fight buggy WiFi access points

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

#7 2011-01-24 21:41:13

Kosmonavt
Member
Registered: 2010-02-15
Posts: 100

Re: Script to fight buggy WiFi access points

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

Board footer

Powered by FluxBB