Keeping my Raspberry Pi Connected

raspi3Not long after the announcement of the new Raspberry Pi 3, I ordered one from my local distributor. One of the reason why I was so eager to get my hand on the new version 3 Pi is because of the built-in WiFi interface. For older Pis, one can add on a supported USB WiFi dongle to create the wireless interface. There are numerous choices available with various speeds depending on different WiFi standard, including the hi-speed 802.11ac, which I have covered here previously.

One issue that I have not mentioned in my article, but I’m sure many have experienced, is that the WiFi connection has the tendency to drop and not able to reconnect itself. (This could be the result of the AP doing the periodic group re-keying process) This is particularly annoying if the Pi was setup as a server which other clients in your network need to make connection to.

I’ve always suspected that this problem is due to driver issue, after all, WiFi dongles are made with chipsets from various manufactures and the driver for Linux were often not written as robust as we like them to be.  By upgrading to Pi version 3, I’m hoping that the driver for Raspberry Pi 3’s build-in WiFi is better written. I was pleased to find that the latest Raspbian (Jessie) distribution comes with driver that work straight out of the box.

After several weeks of testing, I found that the WiFi connection for the Pi 3 did not drop off as often as my other Pis using 3rd party WiFi dongles and drivers, but I am also disappointed to learn that the problem didn’t get eradicated with official hardware/software, the WiFi connection still get dropped off intermittently. So, to solve the problem, I have to revert to use the trusty old shell script running as a cron job. I’ve used this successfully in the past to maintain connections in all my Pis that has a wireless interface.

This is the script I used to maintain the WiFi connection. (Use IP addresses within your own network)


#!/bin/bash
#
DEBUG=off

# use an IP address in your network that is not being used
#TESTIP=A_BAD_IP_ADDRESS
# uncomment above and comment below to test GW ping fail function
TESTIP=YOUR_DEFAULT_GATEWAY_IP
LOGGER="/usr/bin/logger -t $0"
INTERFACE=wlan0
SLEEPWAIT1=1
SLEEPWAIT2=2

function ping_gateway() {
   ping -c2 -I $INTERFACE ${TESTIP} > /dev/null
   if [ $? != 0 ]; then
     if [ $DEBUG == on ]; then
       echo "ping_gateway: Interface up, but can't reach default gateway"
       echo "ping_gateway: Need restarting"
     else
       echo "Interface up, but can't reach default gateway" | $LOGGER
       echo "Need restarting" | $LOGGER
     fi
     return 1
   else
     if [ $DEBUG == on ]; then
       echo "ping_gateway: WiFi interface ok, no action needed"
     else
       echo "WiFi interface ok, no action needed" | $LOGGER
     fi
     return 0
   fi
}

function restart_interface() {
   if [ $DEBUG == on ]; then
     echo "restart_interface: ifdown --force $INTERFACE"
     sleep $SLEEPWAIT1
     echo "restart_interface: ifup $INTERFACE"
     sleep $SLEEPWAIT1
   else
     echo "WiFi down, restarting interface $INTERFACE..." | $LOGGER
     ifdown --force $INTERFACE
     sleep $SLEEPWAIT2
     echo "ifup $INTERFACE" | $LOGGER
     ifup $INTERFACE
     sleep $SLEEPWAIT2
   fi
   if [ $DEBUG == on ]; then
     echo "restart_interface: Restarting ssh daemon..."
   else
     echo "Restarting ssh daemon..." | $LOGGER
     service ssh restart
   fi
}

#main()
if [ -z $(/sbin/iwgetid -r $INTERFACE) ]; then
   restart_interface
else
   ping_gateway
   if [ $? != 0 ]; then
     echo "GW Ping failed, restarting interface" | $LOGGER
     restart_interface
   fi
fi

Save this file as checkwifi and make the file executable:


chmod +x checkwifi

The script has built-in debug option, this can be used to test the script without actually bringing down the interface. To turn on the debug option, editing the script and change the line near the beginning.


DEBUG=on

and save the file.

With DEBUG turned on, no real action will take place but the command that would have caused the action will be printed on screen. You can manually bring the wireless interface up or down to see if the script is able to detect the status of the interface and response accordingly.


sudo ifdown wlan0
./checkwifi
sudo ifup wlan 0
./checkwifi

You can also test the scenario where the interface is apparently up but not reachable to the outside world. I had problem with some drivers for 3rd party WiFi dongles where the interface appears to be up but nothing is reachable until the interface is restarted.  To test this feature, uncomment the first TESTIP and comment out the second TESTIP line to fool the script in trying to ping a non-existing IP address in your network, this way the script should restart the interface. Remember to revert the TESTIP to point to a working IP address such as your default gateway.

Now once you’ve confirmed the script is working, you can turn off DEBUG and put the script to real test. If you’re working via remote connection, make sure you’re logged in via the wired ethernet interface and not the wireless interface as your session will stop once the WiFi interface is brought down. You can bring down the wireless interface manually and execute the script. you may need to run the script as sudoer. i.e.


sudo ./checkwifi

No output will be printed on screen. Instead, you should check your syslog or messages in /var/log/ directory. The script will output what you saw on screen during DEBUG mode to the syslog file. (That’s what the logger command does) You should see entries in the syslog with the tag of the name of the script, in this case ./checkwifi.

Once you’re satisfied with the script and see all the logging in syslog correctly, you can make this script to run periodically as a cron job so that the Pi will test and reset it’s own wireless interface. I placed the script in /etc/cron.hourly directory which will cause the script to run hourly.

Don’t worry about running this script too frequently, the script will not touch the interface if it’s up and reachable to the outside world. You can monitor this script in action by looking at your syslog/messages file. I hope you will find this script useful.

Advertisements