Skip to content

Commit

Permalink
[APP-6881] Add disable wifi power save option (#43)
Browse files Browse the repository at this point in the history
Co-authored-by: James Otting <[email protected]>
  • Loading branch information
ale7714 and Otterverse authored Nov 20, 2024
1 parent 29a0da3 commit b19180f
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 19 deletions.
13 changes: 10 additions & 3 deletions subsystems/provisioning/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ const (
ConnCheckFilepath = "/etc/NetworkManager/conf.d/80-viam.conf"
ConnCheckContents = "[connectivity]\nuri=http://packages.viam.com/check_network_status.txt\ninterval=300\n"

NetworkTypeWifi = "wifi"
NetworkTypeWired = "wired"
NetworkTypeHotspot = "hotspot"
wifiPowerSaveFilepath = "/etc/NetworkManager/conf.d/81-viam-wifi-powersave.conf"
wifiPowerSaveContentsDefault = "# This file intentionally left blank.\n"
wifiPowerSaveContentsDisable = "[connection]\n# Explicitly disable\nwifi.powersave = 2\n"
wifiPowerSaveContentsEnable = "[connection]\n# Explicitly enable\nwifi.powersave = 3\n"
NetworkTypeWifi = "wifi"
NetworkTypeWired = "wired"
NetworkTypeHotspot = "hotspot"

IfNameAny = "any"

Expand Down Expand Up @@ -365,6 +369,9 @@ type Config struct {

// Computed from HotspotPrefix and Manufacturer
hotspotSSID string

// If set, will explicitly enable or disable power save for all wifi connections managed by NetworkManager.
WifiPowerSave *bool `json:"wifi_power_save"`
}

// Timeout allows parsing golang-style durations (1h20m30s) OR seconds-as-float from/to json.
Expand Down
2 changes: 1 addition & 1 deletion subsystems/provisioning/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (w *Provisioning) startGRPC() error {
bind := PortalBindAddr + ":4772"
lis, err := net.Listen("tcp", bind)
if err != nil {
return errw.Wrapf(err, "error listening on: %s", bind)
return errw.Wrapf(err, "listening on: %s", bind)
}

w.grpcServer = grpc.NewServer(grpc.WaitForHandlers(true))
Expand Down
4 changes: 2 additions & 2 deletions subsystems/provisioning/networkmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,13 @@ func (w *Provisioning) StartProvisioning(ctx context.Context, inputChan chan<- u
return err
}
if err := w.activateConnection(ctx, w.Config().HotspotInterface, w.Config().hotspotSSID); err != nil {
return errw.Wrap(err, "error starting provisioning mode hotspot")
return errw.Wrap(err, "starting provisioning mode hotspot")
}

// start portal with ssid list and known connections
if err := w.startPortal(inputChan); err != nil {
err = errors.Join(err, w.deactivateConnection(w.Config().HotspotInterface, w.Config().hotspotSSID))
return errw.Wrap(err, "could not start web/grpc portal")
return errw.Wrap(err, "starting web/grpc portal")
}

w.connState.setProvisioning(true)
Expand Down
6 changes: 3 additions & 3 deletions subsystems/provisioning/portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ func (w *Provisioning) startPortal(inputChan chan<- userInput) error {
w.portalData = &portalData{input: &userInput{}, inputChan: inputChan}

if err := w.startGRPC(); err != nil {
return errw.Wrap(err, "error starting GRPC service")
return errw.Wrap(err, "starting GRPC service")
}

if err := w.startWeb(); err != nil {
return errw.Wrap(err, "error starting web portal service")
return errw.Wrap(err, "starting web portal service")
}

return nil
Expand All @@ -56,7 +56,7 @@ func (w *Provisioning) startWeb() error {
bind := PortalBindAddr + ":80"
lis, err := net.Listen("tcp", bind)
if err != nil {
return errw.Wrapf(err, "error listening on: %s", bind)
return errw.Wrapf(err, "listening on: %s", bind)
}

w.portalData.workers.Add(1)
Expand Down
42 changes: 40 additions & 2 deletions subsystems/provisioning/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (w *Provisioning) init(ctx context.Context) error {
w.updateHotspotSSID(w.cfg)

if err := w.writeDNSMasq(); err != nil {
return errw.Wrap(err, "error writing dnsmasq configuration")
return errw.Wrap(err, "writing dnsmasq configuration")
}

if err := w.testConnCheck(); err != nil {
Expand Down Expand Up @@ -230,6 +230,10 @@ func (w *Provisioning) Start(ctx context.Context) error {
}
}

if err := w.writeWifiPowerSave(ctx); err != nil {
w.logger.Error(errw.Wrap(err, "applying wifi power save configuration"))
}

w.processAdditionalnetworks(ctx)

if err := w.checkOnline(true); err != nil {
Expand Down Expand Up @@ -357,7 +361,7 @@ func (w *Provisioning) processAdditionalnetworks(ctx context.Context) {
for _, network := range w.cfg.Networks {
_, err := w.addOrUpdateConnection(network)
if err != nil {
w.logger.Error(errw.Wrapf(err, "error adding network %s", network.SSID))
w.logger.Error(errw.Wrapf(err, "adding network %s", network.SSID))
continue
}
if network.Interface != "" {
Expand All @@ -375,3 +379,37 @@ func (w *Provisioning) updateHotspotSSID(cfg *Config) {
cfg.hotspotSSID = cfg.hotspotSSID[:32]
}
}

// must be run inside dataMu lock.
func (w *Provisioning) writeWifiPowerSave(ctx context.Context) error {
contents := wifiPowerSaveContentsDefault
if w.cfg.WifiPowerSave != nil {
if *w.cfg.WifiPowerSave {
contents = wifiPowerSaveContentsEnable
} else {
contents = wifiPowerSaveContentsDisable
}
}

isNew, err := agent.WriteFileIfNew(wifiPowerSaveFilepath, []byte(contents))
if err != nil {
return errw.Wrap(err, "writing wifi-powersave.conf")
}

if isNew {
w.logger.Infof("Updated %s to: %q", wifiPowerSaveFilepath, contents)
// Reload NetworkManager to apply changes
if err := w.nm.Reload(0); err != nil {
return errw.Wrap(err, "reloading NetworkManager after wifi-powersave.conf update")
}

ssid := w.netState.ActiveSSID(w.cfg.HotspotInterface)
if w.connState.getConnected() && ssid != "" {
if err := w.activateConnection(ctx, w.cfg.HotspotInterface, ssid); err != nil {
return errw.Wrapf(err, "reactivating %s to enforce powersave setting", ssid)
}
}
}

return nil
}
2 changes: 1 addition & 1 deletion subsystems/provisioning/scanning.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (w *Provisioning) networkScan(ctx context.Context) error {

prevScan, err := wifiDev.GetPropertyLastScan()
if err != nil {
return errw.Wrap(err, "error scanning wifi")
return errw.Wrap(err, "scanning wifi")
}

err = wifiDev.RequestScan()
Expand Down
14 changes: 7 additions & 7 deletions subsystems/provisioning/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,35 +35,35 @@ func (w *Provisioning) writeDNSMasq() error {
func (w *Provisioning) testConnCheck() error {
connCheckEnabled, err := w.nm.GetPropertyConnectivityCheckEnabled()
if err != nil {
return errw.Wrap(err, "error getting NetworkManager connectivity check state")
return errw.Wrap(err, "getting NetworkManager connectivity check state")
}

if !connCheckEnabled {
hasConnCheck, err := w.nm.GetPropertyConnectivityCheckAvailable()
if err != nil {
return errw.Wrap(err, "error getting NetworkManager connectivity check configuration")
return errw.Wrap(err, "getting NetworkManager connectivity check configuration")
}

if !hasConnCheck {
if err := w.writeConnCheck(); err != nil {
return (errw.Wrap(err, "error writing NetworkManager connectivity check configuration"))
return (errw.Wrap(err, "writing NetworkManager connectivity check configuration"))
}
if err := w.nm.Reload(0); err != nil {
return (errw.Wrap(err, "error reloading NetworkManager"))
return (errw.Wrap(err, "reloading NetworkManager"))
}

hasConnCheck, err = w.nm.GetPropertyConnectivityCheckAvailable()
if err != nil {
return errw.Wrap(err, "error getting NetworkManager connectivity check configuration")
return errw.Wrap(err, "getting NetworkManager connectivity check configuration")
}
if !hasConnCheck {
return errors.New("error configuring NetworkManager connectivity check")
return errors.New("configuring NetworkManager connectivity check")
}
}

connCheckEnabled, err = w.nm.GetPropertyConnectivityCheckEnabled()
if err != nil {
return errw.Wrap(err, "error getting NetworkManager connectivity check state")
return errw.Wrap(err, "getting NetworkManager connectivity check state")
}

if !connCheckEnabled {
Expand Down

0 comments on commit b19180f

Please sign in to comment.