100 lines
1.7 KiB
Go
100 lines
1.7 KiB
Go
package devices
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// TODO: Do not use subprocesses here, they are unreliable, provide hidden dependencies and are a common target for vulnerabilities.
|
|
func NewLibgpiod(gpiochip string, powerButtonPin int, powerLEDPin int) Device {
|
|
device := &libgpiod{
|
|
gpiochip: gpiochip,
|
|
powerButtonPin: powerButtonPin,
|
|
powerLEDPin: powerLEDPin,
|
|
lock: sync.Mutex{},
|
|
}
|
|
|
|
return device
|
|
}
|
|
|
|
type libgpiod struct {
|
|
gpiochip string
|
|
powerButtonPin int
|
|
powerLEDPin int
|
|
lock sync.Mutex
|
|
}
|
|
|
|
func (d *libgpiod) Status() (bool, error) {
|
|
d.lock.Lock()
|
|
defer d.lock.Unlock()
|
|
|
|
status, err := d.read(d.powerLEDPin)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return status, nil
|
|
}
|
|
|
|
func (d *libgpiod) PushPowerButton() error {
|
|
d.lock.Lock()
|
|
defer d.lock.Unlock()
|
|
|
|
err := d.write(d.powerButtonPin, 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
time.Sleep(2 * time.Second)
|
|
|
|
err = d.write(d.powerButtonPin, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *libgpiod) write(pin int, value int) error {
|
|
cmd := exec.Command(
|
|
"env", "sh", "-c",
|
|
fmt.Sprintf("gpioset %s %d=%d", d.gpiochip, pin, value),
|
|
)
|
|
|
|
outRaw, err := cmd.Output()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
out := string(outRaw)
|
|
if out == "" {
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("unexpected command output: %s", err)
|
|
}
|
|
|
|
func (d *libgpiod) read(pin int) (bool, error) {
|
|
cmd := exec.Command(
|
|
"env", "sh", "-c",
|
|
fmt.Sprintf("gpioget --bias pull-down %s %d", d.gpiochip, pin),
|
|
)
|
|
|
|
outRaw, err := cmd.Output()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
out := string(outRaw)
|
|
|
|
switch out {
|
|
case "0\n":
|
|
return false, nil
|
|
case "1\n":
|
|
return true, nil
|
|
default:
|
|
return false, fmt.Errorf("unexpected command output: %s", out)
|
|
}
|
|
}
|