#! /bin/bash
#
# hotspot_switcher       script to switch hotspot on/off

# Change to true to enable wconsole functionality.
WCONSOLE=false

NAME="hotspot_switcher"
DESC="Script to switch hotspot on/off"
STATUS_FILE="/etc/wlanpi-state"
HOSTAPD_CONF_FILE="/etc/hostapd/hostapd.conf"
HOTSPOT_CONF_FILE="/etc/wlanpi-hotspot/conf/hostapd.conf"
WCONSOLE_CONF_FILE="/etc/wlanpi-wconsole/conf/hostapd.conf"

if [[ $EUID -ne 0 ]]; then
   echo "Error: This script must be run as root"
   exit 1
fi

###############################################################################
#
# Activate hotspot:
#
# 1. Backup various existing files to allow restoration when hotspot
#    deactivated
# 2. Remove a number of existing files that need to be replaced
# 3. Create links from deleted file locations to hotspot config files
# 4. Create status file to indicate hotspot is active
# 5. Reboot the wlanpi to ensure clean activation
#
###############################################################################

hotspot_on () {

  echo "Starting switch from Classic mode to Hostpot mode"

  if [ "$WCONSOLE" = true ]; then
    # check we have the ser2net service installed
    SER2NET_STATUS=`systemctl status ser2net| grep ser2net.service`
    if  [ -z "$SER2NET_STATUS" ]; then
       echo "Failed: ser2net service not found"
       exit 1
    fi
  fi

  # check what state the WLAN Pi is in classic mode
  PI_STATUS=`cat $STATUS_FILE | grep 'classic'` || true
  if  [ -z "$PI_STATUS" ]; then
     echo "Failed: WLAN Pi is not in Classic mode"
     exit 1
  fi

  # check if the WLAN NIC supports AP mode before switching
  # iw list | awk '/Supported interface modes/, /Band/' | grep '\* AP'
   AP_SUPPORT=`iw list | awk '/Supported interface modes/, /Band/' | grep '\* AP'` || true
   if  [ -z "$AP_SUPPORT" ]; then
     echo "Failed: AP Mode not supported by Wi-Fi adapter"
     exit 1
  fi

  # check if we are using the factory shipped SSID, rename if we are
  echo "Checking for factory default SSID name"
  if grep -q -E "^?ssid=WLAN Pi Default SSID" $HOTSPOT_CONF_FILE && grep -q -E "^?ssid=WLAN Pi Default SSID" $WCONSOLE_CONF_FILE; then
    echo "Creating a unique SSID as using default SSID"

    # Get the last 3 chars of eth0 MAC address
    LAST_3_CHARS_MAC=$(sed s/://g /sys/class/net/eth0/address | grep -o '...$')

    # Check if we got 3 chars
    if [ ${#LAST_3_CHARS_MAC} -ne 3 ]; then
      echo "Failed: Couldn't get eth0 MAC address during unique SSID creation"
      exit 1
    fi

    # Configure the unique SSID
    echo "Applying new SSID: WLAN Pi <last 3 chars of eth0 MAC>"
    sed -i "s/^#\?ssid=.*/ssid=WLAN Pi $LAST_3_CHARS_MAC/" $HOTSPOT_CONF_FILE
    sed -i "s/^#\?ssid=.*/ssid=WLAN Pi $LAST_3_CHARS_MAC/" $WCONSOLE_CONF_FILE

  else
    echo "SSID is already customised"
  fi

  # check if we are using the factory shipped WPA2 passphrase, re-gen if we are
  echo "Checking for factory default WPA2 passphrase"
  if grep -q -E "^?wpa_passphrase=WL@NP123" $HOTSPOT_CONF_FILE && grep -q -E "^?wpa_passphrase=WL@NP123" $WCONSOLE_CONF_FILE; then
    echo "Generating a new random WPA2 passphrase"
    PASSPHRASE=$(tr -dc 'A-Ha-h2-9J-Kj-k2-9M-Nm-n2-9P-Zp-z2-9' </dev/urandom | head -c 12  ; echo)

    # substitute in new random pwd
    echo "Applying randomised passphrase to hotspot and wconsole SSID"
    sed -i "s/^#\?wpa_passphrase=.*/wpa_passphrase=$PASSPHRASE/" $HOTSPOT_CONF_FILE
    sed -i "s/^#\?wpa_passphrase=.*/wpa_passphrase=$PASSPHRASE/" $WCONSOLE_CONF_FILE

  else
    echo "WPA2 passphrase is already customised"
  fi

  echo "Enabling hotspot ..."
  #Backup existing config files
  echo "Backing up existing config files ..."
  cp /etc/default/isc-dhcp-server /etc/default/isc-dhcp-server.hspt
  cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.hspt
  cp /etc/network/interfaces /etc/network/interfaces.hspt
  cp /etc/sysctl.conf /etc/sysctl.conf.hspt
  cp /etc/default/ufw /etc/default/ufw.hspt
  cp /etc/ufw/before.rules /etc/ufw/before.rules.hspt
  if [ "$WCONSOLE" = true ] && [ -e /etc/ser2net.conf ]; then
    cp /etc/ser2net.conf /etc/ser2net.conf.hspt
  fi
  # This file may or may not exist
  if [ -e "$HOSTAPD_CONF_FILE" ]; then
    cp $HOSTAPD_CONF_FILE "${HOSTAPD_CONF_FILE}.hspt"
  fi
  # Remove existing config files
  echo "Removing existing config files ..."
  rm /etc/default/isc-dhcp-server
  rm /etc/dhcp/dhcpd.conf
  rm /etc/network/interfaces
  rm /etc/sysctl.conf
  rm /etc/default/ufw
  rm /etc/ufw/before.rules
  if [ "$WCONSOLE" = true ] && [ -e /etc/ser2net.conf ]; then
    rm /etc/ser2net.conf
  fi
  # This file may or may not exist
  if [ -e "$HOSTAPD_CONF_FILE" ]; then
    rm $HOSTAPD_CONF_FILE
  fi

  # Check if the directory exists
  if [ ! -d "/etc/hostapd" ]; then
      echo "Directory /etc/hostapd does not exist. Creating it..."
      mkdir -p "/etc/hostapd"
  fi

  # Link to hotspot config files
  echo "Creating links to config files ..."
  ln -s /etc/wlanpi-hotspot/default/isc-dhcp-server /etc/default/isc-dhcp-server
  ln -s /etc/wlanpi-hotspot/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf
  ln -s /etc/wlanpi-hotspot/network/interfaces /etc/network/interfaces
  ln -s $HOTSPOT_CONF_FILE $HOSTAPD_CONF_FILE
  ln -s /etc/wlanpi-hotspot/sysctl/sysctl.conf /etc/sysctl.conf
  ln -s /etc/wlanpi-hotspot/default/ufw /etc/default/ufw
  ln -s /etc/wlanpi-hotspot/ufw/before.rules /etc/ufw/before.rules
  if [ "$WCONSOLE" = true ]; then
    ln -s /etc/wlanpi-wconsole/conf/ser2net.conf /etc/ser2net.conf
    # Open up console ports on FW
    ufw allow 2400:2408/tcp
    ufw allow 4800:4808/tcp
    ufw allow 9600:9608/tcp
    ufw allow 19200:19208/tcp
    ufw allow 38400:38408/tcp
    ufw allow 11520:11528/tcp
    ufw allow 2000:2008/tcp
  fi

  # Enable services to start after reboot
  systemctl enable hostapd isc-dhcp-server
  if [ "$WCONSOLE" = true ]; then
    systemctl enable ser2net
  fi

  # Signal that hotspot active
  echo "hotspot" > $STATUS_FILE
  echo "WLAN Pi will now reboot"
  sleep 1
  sync
  reboot
}

###############################################################################
#
# Deactivate hotspot:
#
# 1. Remove links created during activation
# 2. Restore config files backed up during activation
# 3. Remove firewall rules added during activation
# 4. Remove status file to indicate hotspot no longer active
# 5. Reboot wlanpi to provide clean restoration of services
#
###############################################################################

hotspot_off () {

  # check what state the WLAN Pi is in
  PI_STATUS=`cat $STATUS_FILE | grep 'hotspot'` || true
  if  [ -z "$PI_STATUS" ]; then
     echo "Failed: WLAN Pi is not in Hotspot mode"
     exit 1
  fi

  echo "Starting switch from Hotspot mode to Classic mode"

  # Remove links to config files
  echo "Removing links to config files ..."
  unlink /etc/default/isc-dhcp-server
  unlink /etc/dhcp/dhcpd.conf
  unlink /etc/network/interfaces
  unlink $HOSTAPD_CONF_FILE
  unlink /etc/sysctl.conf
  unlink /etc/default/ufw
  unlink /etc/ufw/before.rules
  if [ "$WCONSOLE" = true ]; then
    unlink /etc/ser2net.conf
  fi

  # Restore original config files
  echo "Restoring original config files ..."
  cp /etc/default/isc-dhcp-server.hspt /etc/default/isc-dhcp-server
  cp /etc/dhcp/dhcpd.conf.hspt /etc/dhcp/dhcpd.conf
  cp /etc/network/interfaces.hspt /etc/network/interfaces
  cp /etc/sysctl.conf.hspt /etc/sysctl.conf
  cp /etc/default/ufw.hspt /etc/default/ufw
  cp /etc/ufw/before.rules.hspt /etc/ufw/before.rules
  if [ "$WCONSOLE" = true ]; then
    if [ -e /etc/ser2net.conf.hspt ]; then
      cp /etc/ser2net.conf.hspt /etc/ser2net.conf
    fi
    ufw delete allow 2400:2408/tcp
    ufw delete allow 4800:4808/tcp
    ufw delete allow 9600:9608/tcp
    ufw delete allow 19200:19208/tcp
    ufw delete allow 38400:38408/tcp
    ufw delete allow 2000:2008/tcp
    ufw delete allow 11520:11528/tcp
  fi

  # This file may or may not exist
  if [ -e "${HOSTAPD_CONF_FILE}.hspt" ]; then
    cp "${HOSTAPD_CONF_FILE}.hspt" $HOSTAPD_CONF_FILE
  fi

  # Disable services to start after reboot
  systemctl disable hostapd isc-dhcp-server
  if [ "$WCONSOLE" = true ]; then
    systemctl disable ser2net
  fi

  echo "WLAN Pi will now reboot"
  echo "classic" > $STATUS_FILE
  sleep 1
  sync
  reboot
}

status () {
  PI_STATUS=`cat $STATUS_FILE | grep 'hotspot'` || true
  if  [ -z "$PI_STATUS" ]; then
    echo "Hotspot is currently disabled"
    exit 0
  else
    echo "Hotpot is currently enabled"
    exit 0
  fi

}

version () {
  VERSION=$(apt list --installed wlanpi-hotspot 2>/dev/null | grep wlanpi-hotspot | awk '{print $2}')
  echo "Version: $VERSION" >&2
  exit 0
}

case "$1" in
  on)
        hotspot_on
        ;;
  off)
        hotspot_off
        ;;
  status)
        status
        ;;
  version)
        version;;
  *)
        N=/etc/wlanpi-hotspot/$NAME
        echo "Usage: $N {on|off|status|version}" >&2
        exit 1
        ;;
esac

exit 0