#!/usr/bin/env bash
# $Id: dudhya-wifi-mode 121 2026-09-05 17:26:26Z peter $
#
# Copyright (C) 2026 Péter Felecan
# Assisted by Claude Sonnet 5 (Anthropic)
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# dudhya-wifi-mode --- switch the phone's WiFi between station and
# access-point mode. Switching, not concurrent operation --- see
# Dudhya.org's "WiFi: station/AP mode switching" section and
# ResearchJournal.org for the reasoning. Requires hostapd,
# hostapd-openrc, dnsmasq, wpa_supplicant, and wpa_supplicant-openrc
# already installed, and their config files already in place (see
# WiFi/*.conf.example, copied to their real locations under /etc).
#
# Usage: dudhya-wifi-mode station|ap
#
# NOT YET VERIFIED against real WiFi hardware --- see
# ResearchJournal.org. AP-mode hardware/driver capability was
# confirmed separately (iw list showed AP support), but this script's
# actual station<->AP switching sequence has not itself been run on
# the physical unit yet.

set -euo pipefail

interface="wlan0"
ap_address="192.168.4.1/24"

usage()
{
	echo "usage: $0 station|ap" >&2
	exit 1
}

if [ "$#" -ne 1 ]
then
{
	usage
}
fi

mode="$1"

reset_interface()
{
	ip link set "${interface}" down
	ip addr flush dev "${interface}"
	ip link set "${interface}" up
}

# Unconditionally stop every service either mode could have running,
# regardless of which mode (if any) is currently active. Deliberately
# not skipped even when the target mode's own services are already
# running: re-running this script after only editing a config file
# (e.g. changing hostapd's passphrase) must force a real restart, not
# a no-op --- OpenRC's own "start" on an already-started service does
# not reload it, which would otherwise leave a stale, previously-
# loaded passphrase in memory even though the file has since changed.
# See ResearchJournal.org, 2026-08-01, for the real case this fixes.
stop_all()
{
	rc-service wpa_supplicant stop 2>/dev/null || true
	killall udhcpc 2>/dev/null || true
	rc-service hostapd stop 2>/dev/null || true
	rc-service dnsmasq stop 2>/dev/null || true
}

case "${mode}" in
	station)
	{
		stop_all
		reset_interface
		rc-service wpa_supplicant start
		udhcpc -i "${interface}" -b
		echo "dudhya-wifi-mode: ${interface} now in station mode"
	}
	;;
	ap)
	{
		stop_all
		reset_interface
		ip addr add "${ap_address}" dev "${interface}"
		rc-service hostapd start
		rc-service dnsmasq start
		echo "dudhya-wifi-mode: ${interface} now in AP mode (${ap_address})"
	}
	;;
	*)
	{
		usage
	}
	;;
esac

# Local Variables:
# mode: shell-script
# End:
