111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
package hotspot
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/nemunaire/repeater/internal/models"
|
|
)
|
|
|
|
const (
|
|
AP_INTERFACE = "wlan1"
|
|
HOSTAPD_CONF = "/etc/hostapd/hostapd.conf"
|
|
)
|
|
|
|
// Configure updates the hotspot configuration
|
|
func Configure(config models.HotspotConfig) error {
|
|
hostapdConfig := fmt.Sprintf(`interface=%s
|
|
driver=nl80211
|
|
ssid=%s
|
|
hw_mode=g
|
|
channel=%d
|
|
wmm_enabled=0
|
|
macaddr_acl=0
|
|
auth_algs=1
|
|
ignore_broadcast_ssid=0
|
|
wpa=2
|
|
wpa_passphrase=%s
|
|
wpa_key_mgmt=WPA-PSK
|
|
wpa_pairwise=TKIP
|
|
rsn_pairwise=CCMP
|
|
`, AP_INTERFACE, config.SSID, config.Channel, config.Password)
|
|
|
|
return os.WriteFile(HOSTAPD_CONF, []byte(hostapdConfig), 0644)
|
|
}
|
|
|
|
// Start starts the hotspot
|
|
func Start() error {
|
|
cmd := exec.Command("/etc/init.d/hostapd", "start")
|
|
return cmd.Run()
|
|
}
|
|
|
|
// Stop stops the hotspot
|
|
func Stop() error {
|
|
cmd := exec.Command("/etc/init.d/hostapd", "stop")
|
|
return cmd.Run()
|
|
}
|
|
|
|
// Status checks if the hotspot is running.
|
|
// Returns nil if the service is running, or an error if it's stopped or crashed.
|
|
func Status() error {
|
|
cmd := exec.Command("/etc/init.d/hostapd", "status")
|
|
return cmd.Run()
|
|
}
|
|
|
|
// GetDetailedStatus retrieves detailed status information from hostapd_cli.
|
|
// Returns nil if hostapd is not running or if there's an error.
|
|
func GetDetailedStatus() *models.HotspotStatus {
|
|
cmd := exec.Command("hostapd_cli", "status")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
status := &models.HotspotStatus{}
|
|
lines := strings.Split(string(output), "\n")
|
|
|
|
for _, line := range lines {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" || strings.HasPrefix(line, "Selected interface") {
|
|
continue
|
|
}
|
|
|
|
parts := strings.SplitN(line, "=", 2)
|
|
if len(parts) != 2 {
|
|
continue
|
|
}
|
|
|
|
key := strings.TrimSpace(parts[0])
|
|
value := strings.TrimSpace(parts[1])
|
|
|
|
switch key {
|
|
case "state":
|
|
status.State = value
|
|
case "channel":
|
|
if ch, err := strconv.Atoi(value); err == nil {
|
|
status.Channel = ch
|
|
}
|
|
case "freq":
|
|
if freq, err := strconv.Atoi(value); err == nil {
|
|
status.Frequency = freq
|
|
}
|
|
case "ssid[0]":
|
|
status.SSID = value
|
|
case "bssid[0]":
|
|
status.BSSID = value
|
|
case "num_sta[0]":
|
|
if num, err := strconv.Atoi(value); err == nil {
|
|
status.NumStations = num
|
|
}
|
|
case "hw_mode":
|
|
status.HWMode = value
|
|
case "country_code":
|
|
status.CountryCode = value
|
|
}
|
|
}
|
|
|
|
return status
|
|
}
|