mirror of
https://github.com/anotherhadi/settuings.git
synced 2026-10-05 08:18:23 +02:00
119 lines
2.9 KiB
Go
119 lines
2.9 KiB
Go
package network
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
)
|
|
|
|
var ErrNoWifiDevice = errors.New("no Wi-Fi device found")
|
|
|
|
// WifiDevice returns the first Wi-Fi radio device, if any.
|
|
func WifiDevice() (Device, error) {
|
|
devices, err := ListDevices()
|
|
if err != nil {
|
|
return Device{}, err
|
|
}
|
|
for _, d := range devices {
|
|
if d.Type == "wifi" {
|
|
return d, nil
|
|
}
|
|
}
|
|
return Device{}, ErrNoWifiDevice
|
|
}
|
|
|
|
// WifiNetwork is one access point seen by `nmcli device wifi list`.
|
|
type WifiNetwork struct {
|
|
Active bool // this is the AP we're currently associated with
|
|
SSID string
|
|
BSSID string
|
|
Signal int // 0-100
|
|
Security string
|
|
}
|
|
|
|
func (w WifiNetwork) Secured() bool {
|
|
return w.Security != "" && w.Security != "--"
|
|
}
|
|
|
|
// ListWifi returns visible access points, deduplicated by SSID (keeping the
|
|
// strongest signal seen for each network), sorted strongest-first.
|
|
func ListWifi() ([]WifiNetwork, error) {
|
|
rows, err := runTerse("IN-USE,SSID,BSSID,SIGNAL,SECURITY", "device", "wifi", "list")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bySSID := make(map[string]WifiNetwork)
|
|
order := make([]string, 0, len(rows))
|
|
for _, row := range rows {
|
|
ssid := field(row, 1)
|
|
if ssid == "" {
|
|
continue // hidden network with no broadcast SSID
|
|
}
|
|
signal, _ := strconv.Atoi(field(row, 3))
|
|
net := WifiNetwork{
|
|
Active: field(row, 0) == "*",
|
|
SSID: ssid,
|
|
BSSID: field(row, 2),
|
|
Signal: signal,
|
|
Security: field(row, 4),
|
|
}
|
|
existing, ok := bySSID[ssid]
|
|
if !ok || net.Active || net.Signal > existing.Signal {
|
|
bySSID[ssid] = net
|
|
}
|
|
if !ok {
|
|
order = append(order, ssid)
|
|
}
|
|
}
|
|
|
|
networks := make([]WifiNetwork, 0, len(order))
|
|
for _, ssid := range order {
|
|
networks = append(networks, bySSID[ssid])
|
|
}
|
|
return networks, nil
|
|
}
|
|
|
|
// Rescan asks NetworkManager to trigger a fresh Wi-Fi scan. It returns once
|
|
// the scan is requested, not once it completes; call ListWifi shortly after.
|
|
func Rescan() error {
|
|
_, err := run("device", "wifi", "rescan")
|
|
return err
|
|
}
|
|
|
|
// ConnectWifi joins ssid, creating a new saved profile if none exists yet.
|
|
// Pass an empty password for open networks or when a saved profile already
|
|
// has one.
|
|
func ConnectWifi(ssid, password string) error {
|
|
args := []string{"device", "wifi", "connect", ssid}
|
|
if password != "" {
|
|
args = append(args, "password", password)
|
|
}
|
|
_, err := run(args...)
|
|
return err
|
|
}
|
|
|
|
// DisconnectWifi disconnects the given Wi-Fi device without forgetting it.
|
|
func DisconnectWifi(device string) error {
|
|
_, err := run("device", "disconnect", device)
|
|
return err
|
|
}
|
|
|
|
// SetWifiRadio turns the Wi-Fi radio on or off entirely.
|
|
func SetWifiRadio(on bool) error {
|
|
state := "off"
|
|
if on {
|
|
state = "on"
|
|
}
|
|
_, err := run("radio", "wifi", state)
|
|
return err
|
|
}
|
|
|
|
// RadioEnabled reports whether the Wi-Fi radio is currently switched on.
|
|
func RadioEnabled() (bool, error) {
|
|
out, err := getField("WIFI", "general")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return out == "enabled", nil
|
|
}
|