setup-wifi.sh 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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
  102. install_service() {
  103. print_step "Installing autohotspot service..."
  104. sudo cp "$SCRIPT_DIR/autohotspot.service" /etc/systemd/system/autohotspot.service
  105. sudo systemctl daemon-reload
  106. sudo systemctl enable autohotspot.service
  107. print_success "autohotspot.service installed and enabled"
  108. }
  109. # Main
  110. main() {
  111. echo -e "${GREEN}Dune Weaver Autohotspot Setup${NC}"
  112. echo ""
  113. check_prereqs
  114. create_hotspot_profile
  115. install_dns_redirect
  116. install_configs
  117. install_service
  118. echo ""
  119. echo -e "${GREEN}============================================${NC}"
  120. echo -e "${GREEN} Autohotspot Setup Complete!${NC}"
  121. echo -e "${GREEN}============================================${NC}"
  122. echo ""
  123. echo "On next boot, the Pi will:"
  124. echo " 1. Scan for known WiFi networks (30s timeout)"
  125. echo " 2. If found → connect normally"
  126. 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"
  127. echo ""
  128. echo "Users can connect to the hotspot and open the Dune Weaver app"
  129. echo "to configure WiFi credentials."
  130. echo ""
  131. echo "Commands:"
  132. echo " dw wifi status — Show current WiFi mode"
  133. echo " dw wifi hotspot — Manually switch to hotspot mode"
  134. echo " dw wifi scan — Scan for available networks"
  135. }
  136. main "$@"