Wednesday, October 29, 2014

Raspberry Pi + PiFace Digital : automatically detects loss of connectivity and reboots Gateway Router (cron job)

The problem:
I have a buggy 4G LTE router (a ZTE MF29 used with Airtel 4G here in Pune, India) which hangs around thrice a week causing loss of connectivity until it is rebooted manually by toggling the power button on its back. I cannot get the 4G LTE router exchanged - I am stuck with it. And there hasn't been any firmware updates, neither does it have any option for rebooting using its webpage based management console. So I have to climb up to the small loft where I have kept my network equipment and manually toggle the power switch on the back side of the router.

The problem is compounded by the fact that I have setup a wired LAN between 2 more apartments in my building complex. Three of us friends bought flats in this building together and we had the foresight to ask the builder to run lengths of CAT5e cables through the concealed wiring pipes between our houses. This allowed us to create our own LAN and have a common internet connection.
Now when the Gateway router threw a fit, and I wasn't at home, my friends (cum neighbor) had to use spare keys to get into my house, use a step ladder to access the loft and manually toggle the power on the Gateway router.

The Setting:
Here is the network diagram:

The network diagram of equipment and CAT5e wiring installed in our flats.

Photo of the network equipment installed at my house (A703).
This is the loft which houses the 4G Gateway router and the NAS
along with the two UPSes. The yellow box has the Rapsberry Pi that
is used to reboot the gateway router.

Photo of the network equipment installed at my house (A703).
This is the WiFi Router and the Network Switch. Cat5e cables from the
network switch go to the other two apartments (A602 and A202) through the
concealed wiring PVC pipes in the walls.


The Solution:
I automated the process of rebooting the gateway router using a pair of Raspberry Pi and PiFace Digital. All we need is a combination of a C program and a cron job which checks for internet connectivity (Ping google's Public DNS servers) every 5 minutes and power cycles the gateway router (ZTE MF29). The relay on the PiFace Digital is used to power off and power on the gateway router. I have a Seagate BlackArmor 110 NAS with a spare USB port stationed next to the gateway. I power the Raspberry Pi from that USB port - why add another wall wart if you can steal power from another device nearby.

Steps:
  1. Get a Raspberry Pi and an SD card. Flash the latest Raspbian image onto it and insert the card into the Raspberry Pi.
  2. Insert the PiFace Digital over your Raspberry Pi
  3. My PiFace had issues with the relays not getting toggled with their corresponding jumpers JP6 and JP5 mounted (they are mounted by default). So I had to remove those jumpers on the PiFace and route cables from pins 7 and 6 of the output screw terminals to the proper pins of JP5 and JP6 to switch the relays (see photo below)
    The default settings of JP5 and JP6 - both of them are mounted.
    The image is taken from Sparkfun which also sells PiFace
  4. The modification: unmounted JP5 and JP6 and routed wires to them from terminals 6 and 7
    Install a CAT5e cable between the Rasberry Pi and one of the local LAN ports of the gateway router.
  5. From your laptop, access the Raspberry Pi over SSH using PuTTY (login: pi, password: raspberry)
  6. Now we need to compile the C program for toggling the relay: execute the following commands (while you are in your home directory) to install required packages and get the code for the basic library for piface from Thomas MacPherson's Github repository. the following steps were taken from here.
    1. Install the C compiler:
      sudo apt-get install gcc automake libtool
    2. The PiFace uses the Pi's SPI interface with its own on-board I/O port extender. This means it uses 5 of the Pi's GPIO pins plus power, specifically 1 (+3.3V), 2 (+5V), 6 (0V), 19 (MOSI), 21 (MIS0), 23 (SCLK), 24 (CE0N) and 26 (CE1N). The SPI interface driver is included in the later Raspbian distributions but is not enabled by default so you will need to ensure that it loads each time your start your Pi. You do this by commenting out the blacklist spi-bcm2708 line in your /etc/modprobe.d/raspi-blacklist.conf file by inserting a # in column 1. Edit the file using the command below:
      sudo nano /etc/modprobe.d/raspi-blacklist.conf
    3. Download the source files - this will create a directory called piface:
      git clone https://github.com/thomasmacpherson/piface.git
    4. To install the C pfio library, move into the C directory, then call the setup scripts and then (as root) run the install command. ./autogen.sh takes a while to process with no console output, so don't think it's hung:
      cd piface/c/

      ./autogen.sh

      ./configure

      make

      sudo make install
    5. Runtime libraries have been installed and you need to refresh the library cache:
      sudo ldconfig
  7. Create a C file in your home directory (in ~ and not ~/piface) called toggle_relays.c and edit it using nano. Copy the following code into it:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <stdio.h>
    #include <time.h>
    #include <libpiface-1.0/pfio.h>
    
    int main(void)
    {
     time_t time_elapsed_since_epoch;
     struct timespec required_time, remaining_time;
     pfio_init();
    
     printf("\nTurning ON Relays...");
    
            pfio_digital_write(7, 1);
            pfio_digital_write(6, 1);
    
     //Total delay: 5.5 seconds pfio_digital_write(6, 1);
     required_time.tv_sec = 5; //5.0 seconds pfio_deinit();
     required_time.tv_nsec = 500 * 1000 * 1000L; //0.5 seconds}
    
     printf("Done!");
     fflush(stdout);
    
     if (nanosleep(&required_time, &remaining_time) < 0) {
      printf("Nano sleep system call failed \n");
      return -1;
     }
    
     printf("\nTurning OFF Relays...");
            pfio_digital_write(7, 0);
            pfio_digital_write(6, 0);
     printf("Done!");
    
     return 0;
    }
    
  8. Compile the C file.
    gcc -L/usr/local/lib/ -lpiface-1.0 -o toggle_relays toggle_relays.c
  9. Execute it like so and check to heard the sound of the relays being toggled.
    ./toggle_relays
  10. Route the mains power to the gateway router's wall wart through one of the two relays on the PiFace Digital (see diagram below)
    Wiring the AC mains for powering the gateway router through one of the relays of PiFace
  11. Create a file that contains the script to ping and check if the internet connection on the gateway is working. Name this file as monitor_gateway.sh and copy the following code into it:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # Send two Ping request packets and 4 seconds timeout
    return_value=$(ping -c 2 -W 4 www.google.com)
    return_value=$?
    # Return code for ping are taken from
    # ./OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/include/sysexits.h
     
        case $return_value in
            0)  #Ping reply received
                logger "Ping result: ONLINE"
                ;;
            1)  #Ping sent but reply was not received
                logger "Ping result: OFFLINE (Ping reply not received), Rebooting Airtel LTE Gateway..."
                /home/pi/toggle_relays
                ;;
            *)  #Error
                logger "Ping result: OFFLINE (ping return code: $return_value), Rebooting Airtel LTE Gateway..."
                /home/pi/toggle_relays
                ;;
        esac
    
  12. Mark it as executable
    sudo chmod +x monitor_gateway.sh
  13. To add the script to the crontab to be executed every 5 minutes, execute:
    crontab -e
  14. Add the following line to the end of the file and save it (To save, press Ctrl+O followed by Ctrl+X):
    */5 * * * * /home/pi/monitor_gateway.sh
  15. After 30 mins, check the syslog using the following command. If the router hangs, it will be rebooted and you will see appropriate messages logged there.
    cat /var/log/messages

syslog (cat /var/log/messages) shows the cron job working beautifully
Whenever there is an interruption in service, the executable for toggling the relays is called.
PS. I recommend that you also install RaspControl to allow your Raspberry Pi to be monitored using a webpage based console. 

0 comments:

Post a Comment