setup-wifi.sh 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #!/bin/bash
  2. #
  3. # Dune Weaver - Autohotspot Setup
  4. #
  5. # Sets up the autohotspot system so the Pi creates a "Dune Weaver" WiFi
  6. # hotspot when no known network is available. Users connect to the hotspot
  7. # and configure WiFi through the Dune Weaver app.
  8. #
  9. # DNS redirect for captive portal is handled by NetworkManager's built-in
  10. # dnsmasq (via dnsmasq-shared.d config), not a separate dnsmasq instance.
  11. #
  12. # Run: bash wifi/setup-wifi.sh
  13. # Or: dw wifi setup
  14. #
  15. set -e
  16. # Colors
  17. RED='\033[0;31m'
  18. GREEN='\033[0;32m'
  19. YELLOW='\033[1;33m'
  20. BLUE='\033[0;34m'
  21. NC='\033[0m'
  22. # Determine script and project directories
  23. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  24. PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
  25. HOTSPOT_CON_NAME="DuneWeaver-Hotspot"
  26. HOTSPOT_SSID="Dune Weaver"
  27. HOTSPOT_IP="10.42.0.1/24"
  28. IFACE="wlan0"
  29. NM_DNSMASQ_DIR="/etc/NetworkManager/dnsmasq-shared.d"
  30. print_step() {
  31. echo -e "\n${BLUE}==>${NC} ${GREEN}$1${NC}"
  32. }
  33. print_success() {
  34. echo -e "${GREEN}$1${NC}"
  35. }
  36. print_warning() {
  37. echo -e "${YELLOW}Warning:${NC} $1"
  38. }
  39. print_error() {
  40. echo -e "${RED}Error:${NC} $1"
  41. }
  42. # Check prerequisites
  43. check_prereqs() {
  44. print_step "Checking prerequisites..."
  45. # Check for NetworkManager
  46. if ! command -v nmcli &>/dev/null; then
  47. print_error "NetworkManager (nmcli) not found. This requires Pi OS Trixie or later."
  48. exit 1
  49. fi
  50. # Check for wlan0
  51. if ! nmcli dev show "$IFACE" &>/dev/null; then
  52. print_warning "WiFi interface '$IFACE' not found. Hotspot may not work."
  53. fi
  54. print_success "Prerequisites OK"
  55. }
  56. # Create the NetworkManager hotspot connection profile
  57. create_hotspot_profile() {
  58. print_step "Creating hotspot connection profile..."
  59. # Remove existing profile if present
  60. if nmcli con show "$HOTSPOT_CON_NAME" &>/dev/null; then
  61. echo "Removing existing hotspot profile..."
  62. sudo nmcli con delete "$HOTSPOT_CON_NAME" 2>/dev/null || true
  63. fi
  64. # Read app name from state.json if available
  65. local ssid="$HOTSPOT_SSID"
  66. local state_file="$PROJECT_DIR/state.json"
  67. if [ -f "$state_file" ]; then
  68. local app_name
  69. app_name=$(python3 -c "import json; print(json.load(open('$state_file')).get('app_name', ''))" 2>/dev/null || true)
  70. if [ -n "$app_name" ]; then
  71. ssid="$app_name"
  72. echo "Using app name from state.json: $ssid"
  73. fi
  74. fi
  75. # Create the hotspot profile (open network, no password)
  76. sudo nmcli con add type wifi ifname "$IFACE" mode ap con-name "$HOTSPOT_CON_NAME" \
  77. ssid "$ssid" autoconnect no \
  78. ipv4.method shared ipv4.addresses "$HOTSPOT_IP"
  79. print_success "Hotspot profile created: SSID='$ssid', IP=${HOTSPOT_IP%/*}"
  80. }
  81. # Install DNS redirect config for captive portal
  82. install_dns_redirect() {
  83. print_step "Installing DNS redirect for captive portal..."
  84. # NetworkManager's shared mode runs its own dnsmasq.
  85. # Configs in dnsmasq-shared.d/ are loaded automatically when a shared
  86. # connection is active. This redirects ALL DNS to the Pi's hotspot IP,
  87. # triggering captive portal detection on phones/tablets.
  88. sudo mkdir -p "$NM_DNSMASQ_DIR"
  89. sudo cp "$SCRIPT_DIR/dnsmasq-hotspot.conf" "$NM_DNSMASQ_DIR/dune-weaver-captive.conf"
  90. print_success "DNS redirect installed at $NM_DNSMASQ_DIR/dune-weaver-captive.conf"
  91. }
  92. # Copy autohotspot script and service
  93. install_configs() {
  94. print_step "Installing autohotspot script..."
  95. # Copy autohotspot script
  96. sudo cp "$SCRIPT_DIR/autohotspot" /usr/local/bin/autohotspot
  97. sudo chmod +x /usr/local/bin/autohotspot
  98. echo "Installed /usr/local/bin/autohotspot"
  99. print_success "Autohotspot script installed"
  100. }
  101. # Install and enable the systemd service and timer
  102. install_service() {
  103. print_step "Installing autohotspot service and timer..."
  104. # Boot service: runs once at startup with 30s scan
  105. sudo cp "$SCRIPT_DIR/autohotspot.service" /etc/systemd/system/autohotspot.service
  106. # Periodic check: runs every 60s to detect WiFi drops and recover
  107. sudo cp "$SCRIPT_DIR/autohotspot-check.service" /etc/systemd/system/autohotspot-check.service
  108. sudo cp "$SCRIPT_DIR/autohotspot-check.timer" /etc/systemd/system/autohotspot-check.timer
  109. sudo systemctl daemon-reload
  110. sudo systemctl enable autohotspot.service
  111. sudo systemctl enable --now autohotspot-check.timer
  112. print_success "autohotspot.service and autohotspot-check.timer installed and enabled"
  113. }
  114. # Main
  115. main() {
  116. echo -e "${GREEN}Dune Weaver Autohotspot Setup${NC}"
  117. echo ""
  118. check_prereqs
  119. create_hotspot_profile
  120. install_dns_redirect
  121. install_configs
  122. install_service
  123. echo ""
  124. echo -e "${GREEN}============================================${NC}"
  125. echo -e "${GREEN} Autohotspot Setup Complete!${NC}"
  126. echo -e "${GREEN}============================================${NC}"
  127. echo ""
  128. echo "On next boot, the Pi will:"
  129. echo " 1. Scan for known WiFi networks (30s timeout)"
  130. echo " 2. If found → connect normally"
  131. echo " 3. If not found → create a '$(nmcli -t -f 802-11-wireless.ssid con show "$HOTSPOT_CON_NAME" 2>/dev/null | cut -d: -f2 || echo "$HOTSPOT_SSID")' hotspot"
  132. echo ""
  133. echo "A periodic check runs every 60 seconds to:"
  134. echo " - Fall back to hotspot if WiFi drops"
  135. echo " - Reconnect to known WiFi when it becomes available"
  136. echo ""
  137. echo "Users can connect to the hotspot and open the Dune Weaver app"
  138. echo "to configure WiFi credentials."
  139. echo ""
  140. echo "Commands:"
  141. echo " dw wifi status — Show current WiFi mode"
  142. echo " dw wifi hotspot — Manually switch to hotspot mode"
  143. echo " dw wifi scan — Scan for available networks"
  144. }
  145. main "$@"