Automatically Restoring DFS Channels After Radar Detection

Dynamic Frequency Selection (DFS) is a regulatory requirement for wireless devices operating in certain 5GHz frequency bands. It ensures that these devices do not interfere with radar systems by dynamically switching channels when radar signals are detected. Sometimes it happens even there is no radar operating in the area. In this articles we shall guide you through creating a script to automatically restart your 5GHz radio of Dual Band Openwrt Router using a DFS channel upon radar detection.

Introduction to DFS

DFS is crucial for maintaining the integrity of radar operations and ensuring that wireless networks comply with regulatory standards. When a radar signal is detected on a DFS channel, the wireless device must vacate the channel and switch to another one. This process can cause temporary disruptions in the network, but it is necessary to prevent interference with radar systems.

The Challenge

In some cases, the automatic channel switching might not work as expected, or the device might not switch to the desired channel. To address this, we can create a script that monitors the current channel and frequency of the 5GHz radio and restarts it if necessary.

Step-by-Step Explanation of the Script:

1. Configuration Section

RADIO="radio1"
MAX_RESTARTS=2
RESTART_INTERVAL=3600  # 1 hour in seconds
LOG_FILE="/tmp/check_radio_channel.log"
MAX_LOG_SIZE=10240  # 10 KB
  • RADIO: Specifies the radio interface to monitor (e.g., radio1).
  • MAX_RESTARTS: Maximum number of restarts allowed within the specified interval.
  • RESTART_INTERVAL: Time interval (in seconds) within which the maximum restarts are counted.
  • LOG_FILE: Path to the log file.
  • MAX_LOG_SIZE: Maximum size of the log file before it gets truncated.

2. Function Definitions

  • get_current_channel: Retrieves the current channel setting of the specified radio.
get_current_channel() {
    uci get wireless.$RADIO.channel
}
  • get_current_frequency: Retrieves the current operating frequency of the specified radio.
get_current_frequency() {
    iwinfo $RADIO info | grep 'Channel:' | awk '{print $4}'
}
  • restart_radio: Restarts the specified radio interface.
restart_radio() {
    wifi down $RADIO && wifi up $RADIO
}
  • truncate_log: Truncates the log file if it exceeds the specified maximum size.
truncate_log() {
    if [ -f $LOG_FILE ]; then
        log_size=$(wc -c < "$LOG_FILE")
        if [ "$log_size" -ge "$MAX_LOG_SIZE" ]; then
            : > $LOG_FILE
            echo "Log file truncated" > $LOG_FILE
        fi
    fi
}

3. Main Script Execution

  • Truncate Log: Ensures the log file does not exceed the maximum size.
truncate_log
  • Get Current Channel and Frequency: Retrieves the current channel and frequency.
current_channel=$(get_current_channel)
current_frequency=$(get_current_frequency)
  • Check if Channel is Set to Auto: If the channel is set to “auto”, the script exits without taking any action.
if [ "$current_channel" = "auto" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Channel is set to auto, no action taken" >> $LOG_FILE
    exit 0
fi
  • Initialize Restart Count and Time: Initializes variables to keep track of the restart count and the last restart time.
restart_count=0
last_restart_time=0
  • Get Current Time: Retrieves the current time in seconds since the epoch.
current_time=$(date +%s)
  • Check Channel and Frequency Mismatch: If the current channel does not match the current frequency, the script checks if a restart is needed.
if [ "$current_channel" != "$current_frequency" ]; then
    if [ $((current_time - last_restart_time)) -le $RESTART_INTERVAL ]; then
        if [ $restart_count -lt $MAX_RESTARTS ]; then
            restart_radio
            restart_count=$((restart_count + 1))
            last_restart_time=$current_time
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Maximum restarts reached within an hour" >> $LOG_FILE
        fi
    else
        restart_radio
        restart_count=1
        last_restart_time=$current_time
    fi
fi

Full Script

Here is the complete script with all the explained sections combined:

#!/bin/sh

# Configuration
RADIO="radio1"
MAX_RESTARTS=2
RESTART_INTERVAL=3600  # 1 hour in seconds
LOG_FILE="/tmp/check_radio_channel.log"
MAX_LOG_SIZE=10240  # 10 KB

# Function to get the current channel of the specified radio
get_current_channel() {
    uci get wireless.$RADIO.channel
}

# Function to get the current frequency of the specified radio
get_current_frequency() {
    iwinfo $RADIO info | grep 'Channel:' | awk '{print $4}'
}

# Function to restart the radio
restart_radio() {
    # Restart the radio
    wifi down $RADIO && wifi up $RADIO
}

# Function to truncate the log file if it exceeds the maximum size
truncate_log() {
    if [ -f $LOG_FILE ]; then
        log_size=$(wc -c < "$LOG_FILE")
        if [ "$log_size" -ge "$MAX_LOG_SIZE" ]; then
            : > $LOG_FILE
            echo "Log file truncated" > $LOG_FILE
        fi
    fi
}

# Truncate log if necessary
truncate_log

# Get current channel and frequency
current_channel=$(get_current_channel)
current_frequency=$(get_current_frequency)

# Check if the channel is set to auto
if [ "$current_channel" = "auto" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Channel is set to auto, no action taken" >> $LOG_FILE
    exit 0
fi

# Initialize restart count and time
restart_count=0
last_restart_time=0

# Get current time
current_time=$(date +%s)

# Check if the current channel is not the same as the current frequency
if [ "$current_channel" != "$current_frequency" ]; then
    # Check if the restart count is less than the maximum allowed restarts within an hour
    if [ $((current_time - last_restart_time)) -le $RESTART_INTERVAL ]; then
        if [ $restart_count -lt $MAX_RESTARTS ]; then
            restart_radio
            restart_count=$((restart_count + 1))
            last_restart_time=$current_time
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Maximum restarts reached within an hour" >> $LOG_FILE
        fi
    else
        # Reset the restart count if more than an hour has passed
        restart_radio
        restart_count=1
        last_restart_time=$current_time
    fi
fi

How to use this script:

Step 1: Downloading WinSCP

  • Visit the Official Website: Go to the WinSCP download page.
  • Download the Installer: Click on the download link to get the latest version of WinSCP. Save the installer to an easily accessible location, such as your desktop or Downloads folder.

Step 2: Installing WinSCP

  1. Run the Installer: Double-click the downloaded installer file to start the installation process.
  2. Follow the Installation Wizard:
    • Language Selection: Choose your preferred language.
    • License Agreement: Review and accept the license agreement.
    • Setup Type: Select “Typical installation” for a standard setup.
    • User Interface Style: Choose between the Commander interface (similar to Total Commander) or the Explorer interface (similar to Windows Explorer).
  3. Complete the Installation: Click “Install” and wait for the installation to finish. You may need to restart your computer or Windows File Explorer.

Step 3: Connecting to Your Router Using WinSCP

  1. Open WinSCP: Launch WinSCP from your Start menu or desktop shortcut.
  2. Create a New Session:
    • File Protocol: Select SCP or SFTP.
    • Hostname: Enter the IP address of your router (e.g., 192.168.1.1).
    • Port Number: Use 22 for SSH.
    • Username: Enter root or the appropriate username for your router.
    • Password: Enter your router’s password.
  3. Login: Click “Login” to connect to your router. You may need to accept the host key if prompted.

Step 4: Creating a File in a Given Directory

  • Navigate to the Directory: Use the WinSCP interface to navigate to the directory where you want to create the file.
  • Open Terminal: Click on the “Commands” menu and select “Open Terminal”.
  • Create the File: In the terminal, use the touch command to create a new file. For example:
touch /etc/check_radio_channel.sh
  • Copy Script: Open the newly created file by write click and choose edit. Copy and paste the script in it and save.

Step 5: Making the Script Executable

  • Open Terminal in WinSCP: If not already open, use the “Commands” menu to open the terminal.
  • Change Permissions: Use the chmod command to make the script executable:
chmod +x /root/check_radio_channel.sh

Step 6: Setting Up the Cron Job Using LuCI Web Interface

  • Access LuCI: Open your web browser and navigate to your router’s LuCI web interface (usually http://192.168.1.1).
  • Login: Enter your username and password to log in.
  • Navigate to System > Scheduled Tasks: This is where you can manage cron jobs.
  • Add a Cron Job: Enter the cron job details to run your script at the desired intervals. For example, to run the script every minute, add:
* * * * * /etc/check_radio_channel.sh >> /tmp/check_radio_channel.log 2>&1
  • Save: Click “Save” to save the cron job.
  • Navigate to System > Startup: Look for cronInitscript and tap on Restart.

Step 7: Checking logs

  • Script is saving logs to /tmp/check_radio_channel.log file
  • Navigate to /tmp direcotry using Winscp and open check_radio_channel.log file.

 

 

 

 

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x