Keeping AirPort Connected to a Specific Access Point
The wireless LAN access point we have at our house is an old Belkin box that only supports the 802.11b standard, which is the slowest of the few "versions" of WiFi. The speed hasn't been a big issue -- we rarely need to move large files over the internal network, and if we do, we plug in an Ethernet cable. Even the fact that it sometimes replaces web pages your browser requests with advertisements of some fantastic parental filter feature it has has not annoyed us enough to take action. What has been an issue, though, is the fact that it frequently drops connections with our Macbooks.
The Macbooks' AirPort WLAN adapters have been working in other networks without running into any major problems, and the Belkin access point didn't drop connections with any of the other laptops we've used at home, so this leads me to believe this is some sort of compatibility issue between the AirPort and the Belkin. The AirPort works generally well and just as expected when connected to the access point, but frequently the connection just inexplicably drops, and to get it back, we have to turn AirPort off and then back on again (via the menu bar item, for example,) and even then it sometimes doesn't reconnect, making us repeat the process (maybe a couple of times, depending on how cranky a mood it is in.)
The first solution I made for this was a small script that would reconnect to the access point, which I made an application out of with Platypus, and put on my desktop for some double-clicking action. Whenever the connection would drop, I'd use the Exposé "show desktop" action (I've set it to be triggered whenever I move my mouse to a specific corner of the screen) and double-click to invoke the reconnect app to get me back online. Quite soon, though, having to keep repeating this became a bit annoying as well. So then I decided to extend this script to run a loop that checks the AirPort connection status at regular intervals, and reconnects automatically if the connection has dropped. To enable easy invocation of this script, and to be able to get the output to be displayed in a nice GUI window, I again used Platypus to make it into an application. This has been working pretty well for me so far, so I decided to share the fruits of my labour with you here:
Keep in mind, this is not the most easy-to-use solution since you have to go inside the application bundle, find the script file, open it up in a text editor, and change the settings inside the script to be able to tell it which access point to connect to and with which password.
Download the application here: keepConnectedToWLANAP-v0.8.dmg
Or check out the source here:
#!/bin/bash
# ----------------------------------------
# DESCRIPTION:
#
# Keep airport associated with a specific
# access point
#
#
# Copyright (c) 2008 Ali Rantakari
# http://hasseg.org
#
# ----------------------------------------
# settings begin here:
# --------------------
# SSID of WLAN AP to connect to
TOSSID="MYSSID"
# WLAN AP password
WITHPW="0xf0f0f0f0f0f0f0f0f0f0f0f0f0"
# where to find the airport utility (it's here in Tiger and Leopard, at least)
AP="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport"
CHECKINTERVAL=5 # how often to check AirPort status
CHECKINTERVALWHENOFF=20 # how often to check AirPort status if it's been off
TRIES=7 # how many times to retry connecting if not successful
RETRYDELAY=3 # how many seconds to wait before retrying
# ------ settings end here. implementation begins below
#if [ "$1" == "-xv" ];then
# VERBOSE="true"
#else
# VERBOSE="false"
#fi
VERBOSE="true"
is_on()
{
if [ "`$AP --getinfo | grep -c \"AirPort: Off\"`" == "1" ];then
echo "false"
else
echo "true"
fi
}
is_associated()
{
if [ "`$AP --getinfo | grep SSID | grep -v BSSID | grep -c $TOSSID`" == "0" ];then
echo "false"
else
echo "true"
fi
}
connect()
{
if [ "$VERBOSE" == "true" ];then
echo " "
fi
I=0
while [ "$I" -lt "$TRIES" ]
do
if [ "$VERBOSE" == "true" ];then
# if [ "$I" == "1" ];then
# echo " "
# echo " (trying $(($TRIES-1)) more times)"
# echo " "
# fi
echo -n " Trying to connect to $TOSSID... "
fi
$AP --associate=$TOSSID --password=$WITHPW
if [ "`is_associated`" == "true" ];then
# ok
I=$TRIES
if [ "$VERBOSE" == "true" ];then
echo "...done!"
fi
else
# not ok -> retry
I=$(($I + 1))
if [ "$VERBOSE" == "true" ];then
if [ "$I" == "$TRIES" ];then
echo "...unsuccessful."
else
echo -n "...unsuccessful."
fi
fi
if [ "$I" -lt "$TRIES" ];then
if [ "$VERBOSE" == "true" ];then
echo -n " Retrying in "
fi
J=$RETRYDELAY
while [ "$J" -gt "-1" ]
do
J=$(($J - 1))
sleep 1
if [ "$VERBOSE" == "true" ];then
echo -n "$(($J+1))"
fi
done
if [ "$VERBOSE" == "true" ];then
echo " "
fi
fi
fi
done
if [ "$VERBOSE" == "true" ];then
echo " "
fi
}
CURRCHECKINTERVAL=$CHECKINTERVAL
LASTONSTATUS="on"
LASTASSOCIATEDSTATUS="false"
FIRSTRUN="true"
# main loop
while [ "1" == "1" ]
do
if [ "`is_on`" == "false" ];then
if [ "$VERBOSE" == "true" ]&&[ "$LASTONSTATUS" == "on" ];then
echo "- Airport turned off, will not try to connect until it's turned on again."
fi
LASTONSTATUS="off"
CURRCHECKINTERVAL=$CHECKINTERVALWHENOFF
else
if [ "`is_associated`" == "true" ];then
if [ "$VERBOSE" == "true" ]&&[ "$LASTASSOCIATEDSTATUS" == "false" ];then
echo "- Already connected to $TOSSID."
fi
LASTASSOCIATEDSTATUS="true"
else
if [ "$VERBOSE" == "true" ]&&[ "$FIRSTRUN" == "false" ];then
if [ "$LASTONSTATUS" == "off" ];then
echo "- Airport is on again, initiating connect procedure:"
else
if [ "$LASTASSOCIATEDSTATUS" == "true" ];then
echo "- Connection to $TOSSID lost. Initiating connect procedure:"
else
echo "- Trying to connect again:"
fi
fi
fi
connect
if [ "`is_associated`" == "true" ];then
LASTASSOCIATEDSTATUS="true"
else
LASTASSOCIATEDSTATUS="false"
fi
fi
LASTONSTATUS="on"
CURRCHECKINTERVAL=$CHECKINTERVAL
fi
sleep $CURRCHECKINTERVAL
FIRSTRUN="false"
done
2 Comments
That is just what need ! But the application always say that root privileges are required when it trying to connect. could you help me please :-)
This access rights change for the airport command-line utility, I believe, was part of a recent OS update (either the recent security update or 10.5.3,) and it seems to have been causing some trouble here. You can modify the script to run it via sudo, though, but I’ve noticed that even when I get it working like this the airport command-line utility still “hangs” sometimes and fails to return, forcing me to restart the script. To make the script run it via sudo, make the change to this line:
sudo $AP --associate=$TOSSID --password=$WITHPW