From 3a42389ebd0c4eb9350d872e368843e911d275f8 Mon Sep 17 00:00:00 2001 From: KemoNine Date: Wed, 26 Aug 2020 01:11:25 -0400 Subject: [PATCH] Initial port of wifi config utility from python 3 --- cmd/wifi/README.md | 5 ++ cmd/wifi/wifi.go | 123 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 cmd/wifi/README.md create mode 100644 cmd/wifi/wifi.go diff --git a/cmd/wifi/README.md b/cmd/wifi/README.md new file mode 100644 index 0000000..4903652 --- /dev/null +++ b/cmd/wifi/README.md @@ -0,0 +1,5 @@ +# wifi + +This is the WiFi auto-configuration code for the PiFrame project. + +This utility will look for a USB disk containing a ```wifi.txt``` file contianing the ```essid``` and ```password``` for the WiFi setup. If the file is found on a non-mounted USB disk, it will re-configure wifi according to the contents of the file. diff --git a/cmd/wifi/wifi.go b/cmd/wifi/wifi.go new file mode 100644 index 0000000..2aa576d --- /dev/null +++ b/cmd/wifi/wifi.go @@ -0,0 +1,123 @@ +package main + +import ( + "io/ioutil" + "log" + "os" + "os/exec" + "strings" +) + +// Various commands that we need for this process +const ( + CMD_BLKID = "/usr/sbin/blkid" + CMD_FINDMNT = "/usr/bin/findmnt" + CMD_MOUNT = "/usr/bin/mount" + CMD_NMCLI = "/usr/bin/nmcli" + CMD_UMOUNT = "/usr/bin/umount" +) + +// Various file paths we need +const ( + MOUNTPOINT = "/var/wifi" + CONFIG_FILE = "wifi.txt" + CONFIG_PATH_FULL = MOUNTPOINT + "/" + CONFIG_FILE +) + +func main() { + // Check if mountpoint exists and create if it doesn't + if _, err := os.Stat(MOUNTPOINT); os.IsNotExist(err) { + if err := os.Mkdir(MOUNTPOINT, 0755); err != nil { + log.Fatalf("Could not create mountpoint %s : %s ", MOUNTPOINT, err) + } + } + + // Find all blkids that we need to evaluate for wifi config + blkidOut, err := exec.Command(CMD_BLKID, "-o", "device").Output() + if err != nil { + log.Fatalf("Error running %s : %s", CMD_BLKID, err) + } + blkids := string(blkidOut) + // Check blkids to see if they are already mounted + // skip if mounted, skip zram (never mounted) as well + for _, blkid := range strings.Split(strings.TrimSuffix(blkids, "\n"), "\n") { + if blkid == "" || strings.Contains(blkid, "zram") { + continue + } + // SKIP err check here, findmnt will exit w/ status 1 if it's not mounted + // We obviously don't care if it can't find a mountpoint, that's the intent here + findmntOut, _ := exec.Command(CMD_FINDMNT, "-n", "-o", "TARGET", blkid).Output() + mnt := strings.Trim(string(findmntOut), "\n") + if mnt == "" { + // Mount the unmounted volume + err := exec.Command(CMD_MOUNT, blkid, MOUNTPOINT).Run() + if err != nil { + log.Fatalf("Could not mount %s : %s", blkid, err) + } + // Check if the wifi config exists at the new mountpoint, we don't care if it's not present so just keep going + if _, err := os.Stat(CONFIG_PATH_FULL); os.IsNotExist(err) { + if err != nil { + log.Println("WiFi config not found") + err := exec.Command(CMD_UMOUNT, MOUNTPOINT).Run() + if err != nil { + log.Fatalf("Could not unmount %s : %s ", MOUNTPOINT, err) + } + continue + } + } + // Sanity check config file + stat, err := os.Stat(CONFIG_PATH_FULL) + if err != nil { + log.Fatalf("Error getting config file information : %s", err) + } + if stat.Size() > 100000 { + log.Fatal("Config is >100kb, cannot process") + } + if !stat.Mode().IsRegular() { + log.Fatal("Config is NOT a regular (TEXT) file, cannot process") + } + // Open and read wifi config file + configFileContents, err := ioutil.ReadFile(CONFIG_PATH_FULL) + if err != nil { + log.Fatalf("Error reading file %s : %s", CONFIG_PATH_FULL, err) + } + config := strings.Split(strings.Trim(string(configFileContents), "\n"), "\n") + // Final sanity checks + if len(config) != 2 { + log.Fatal("Config has incorrect number of lines, it should only be 2 lines") + } + // Doing stuff with the file contents goes here + essid := config[0] + password := config[1] + log.Printf("Using config: %s / %s for WiFi\n", essid, password) + // Cleanup existing WiFi connections + nmcliOut, err := exec.Command(CMD_NMCLI, "-t", "connection", "show").Output() + if err != nil { + log.Fatalf("Error running %s : %s", CMD_NMCLI, err) + } + connections := strings.Split(strings.Trim(string(nmcliOut), "\n"), "\n") + for _, connection := range connections { + details := strings.Split(connection, ":") + if details[2] != "802-11-wireless" { + continue + } + log.Printf("Cleaning up WiFi connection %s", details[0]) + err := exec.Command(CMD_NMCLI, "connection", "del", details[1]).Run() + if err != nil { + log.Fatalf("Error running %s : %s", CMD_NMCLI, err) + } + } + // Create new WiFi connection with network manager + log.Printf("Connecting to %s with password %s\n", essid, password) + err = exec.Command(CMD_NMCLI, "d", "wifi", "connect", essid, "password", password).Run() + if err != nil { + log.Fatalf("Error running %s : %s", CMD_NMCLI, err) + } + // Unmount the filesystem and continue + err = exec.Command(CMD_UMOUNT, MOUNTPOINT).Run() + if err != nil { + log.Fatalf("Could not unmount %s : %s ", MOUNTPOINT, err) + } + } + } +}