210 lines
5.3 KiB
Go
210 lines
5.3 KiB
Go
package owrt
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// UCIWirelessInterface is the description of an Wireless interface (cf Openwrt doc) on top of an Wireless Device
|
|
type UCIWirelessInterface struct {
|
|
Name string
|
|
Index int
|
|
Device string
|
|
DevicePath string
|
|
SysDevName string
|
|
Mode string
|
|
Disabled bool
|
|
Ssid string
|
|
Bssid string
|
|
Network string
|
|
Encryption string
|
|
Key string
|
|
Country string
|
|
}
|
|
|
|
// NewUCIWirelessInterface builds a new UCIWirelessInterface instance
|
|
func NewUCIWirelessInterface() *UCIWirelessInterface {
|
|
return &UCIWirelessInterface{}
|
|
}
|
|
|
|
// GetSysDevName looks for the system name of Wireless Interface
|
|
func (wi *UCIWirelessInterface) GetSysDevName(sysDir string) string {
|
|
var found string
|
|
|
|
if wi.SysDevName != "" {
|
|
return wi.SysDevName
|
|
}
|
|
|
|
if sysDir == "" {
|
|
sysDir = "/sys/devices/platform"
|
|
}
|
|
|
|
if _, err := os.Stat(sysDir); os.IsNotExist(err) {
|
|
return "ERROR123-FILE-DONES-NOT-EXIST"
|
|
}
|
|
|
|
err := filepath.Walk(sysDir, func(path string, f os.FileInfo, _ error) error {
|
|
patt := fmt.Sprintf("%s/%s/.*/address", wi.DevicePath, "net")
|
|
r, err := regexp.MatchString(patt, path)
|
|
if err == nil && r {
|
|
res := strings.Split(path, "/")
|
|
idx := len(res) - 2
|
|
found = res[idx]
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err.Error()
|
|
}
|
|
wi.SysDevName = found
|
|
return found
|
|
}
|
|
|
|
// Create add a new entry for wifi interface in UCI Configuration
|
|
func (wi *UCIWirelessInterface) Create(uci *UCI) *Action {
|
|
var confPrefix string
|
|
addRes := uci.AddWireless()
|
|
if addRes.ReturnCode != 0 {
|
|
return addRes
|
|
}
|
|
if wi.Index <= 0 {
|
|
confPrefix = fmt.Sprintf("wireless.@wifi-iface[%d]", len(uci.Wireless.Interfaces))
|
|
} else {
|
|
confPrefix = fmt.Sprintf("wireless.@wifi-iface[%d]", wi.Index)
|
|
}
|
|
conf := make(map[string][]string)
|
|
|
|
conf["network"] = append(conf["network"], fmt.Sprintf("%s.network", confPrefix), wi.Network)
|
|
conf["ssid"] = append(conf["ssid"], fmt.Sprintf("%s.ssid", confPrefix), wi.Ssid)
|
|
conf["enc"] = append(conf["enc"], fmt.Sprintf("%s.encryption", confPrefix), wi.Encryption)
|
|
conf["device"] = append(conf["device"], fmt.Sprintf("%s.device", confPrefix), wi.Device)
|
|
conf["mode"] = append(conf["mode"], fmt.Sprintf("%s.mode", confPrefix), wi.Mode)
|
|
conf["bssid"] = append(conf["bssid"], fmt.Sprintf("%s.bssid", confPrefix), wi.Bssid)
|
|
conf["key"] = append(conf["key"], fmt.Sprintf("%s.key", confPrefix), wi.Key)
|
|
conf["disabled"] = append(conf["disabled"], fmt.Sprintf("%s.disabled", confPrefix), "0")
|
|
conf["country"] = append(conf["country"], fmt.Sprintf("%s.country", confPrefix), wi.Country)
|
|
|
|
for _, value := range conf {
|
|
if value[1] != "" {
|
|
result := uci.Set(value[0], value[1])
|
|
if result.ReturnCode != 0 {
|
|
return result
|
|
}
|
|
}
|
|
}
|
|
|
|
return &Action{
|
|
CommandResult: &CommandResult{
|
|
Stdout: "",
|
|
Stderr: "",
|
|
ReturnCode: 0,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Save commit and relaod configuration (writes it to files !)
|
|
func (wi *UCIWirelessInterface) Save(uci *UCI) *Action {
|
|
commitRes := uci.Commit()
|
|
if commitRes.ReturnCode != 0 {
|
|
return commitRes
|
|
}
|
|
|
|
reload := uci.Reload()
|
|
return reload
|
|
}
|
|
|
|
// SysAdd creates the interface in the system using iw command
|
|
func (wi *UCIWirelessInterface) SysAdd(uci *UCI) *Action {
|
|
cmd := "iw"
|
|
opt := "phy"
|
|
phydev := fmt.Sprintf("phy%d", wi.Index)
|
|
what := "interface"
|
|
act := "add"
|
|
tpe := "managed"
|
|
|
|
if wi.SysDevName == "" {
|
|
wi.SysDevName = fmt.Sprintf("tmp.radio%d", wi.Index)
|
|
}
|
|
|
|
res := uci.exec.Run(cmd, opt, phydev, what, act, wi.SysDevName, "type", tpe)
|
|
return &Action{
|
|
CommandResult: res,
|
|
Command: fmt.Sprintf("%s %s %s %s %s %s %s %s", cmd, opt, phydev, what, act, wi.SysDevName, "type", tpe),
|
|
}
|
|
}
|
|
|
|
// SysDel deletes the interface in the system using iw command
|
|
func (wi *UCIWirelessInterface) SysDel(uci *UCI) *Action {
|
|
cmd := "iw"
|
|
opt := "dev"
|
|
act := "del"
|
|
|
|
if wi.SysDevName == "" {
|
|
wi.SysDevName = fmt.Sprintf("tmp.radio%d", wi.Index)
|
|
}
|
|
|
|
res := uci.exec.Run(cmd, opt, wi.SysDevName, act)
|
|
return &Action{
|
|
CommandResult: res,
|
|
Command: fmt.Sprintf("%s %s %s %s", cmd, opt, wi.SysDevName, act),
|
|
}
|
|
}
|
|
|
|
// Up brings the interface up in the system using ip command
|
|
func (wi *UCIWirelessInterface) Up(uci *UCI) *Action {
|
|
cmd := "ip"
|
|
opt := "link"
|
|
act := "set"
|
|
wht := "dev"
|
|
|
|
res := uci.exec.Run(cmd, opt, act, wht, wi.SysDevName, "up")
|
|
return &Action{
|
|
CommandResult: res,
|
|
}
|
|
}
|
|
|
|
// Delete remove wifi interface from UCI Configuration
|
|
func (wi *UCIWirelessInterface) Delete(uci *UCI) *Action {
|
|
toDelete := fmt.Sprintf("wireless.@wifi-iface[%d]", wi.Index)
|
|
del := uci.Delete(toDelete)
|
|
if del.ReturnCode != 0 {
|
|
return del
|
|
}
|
|
return uci.Commit()
|
|
}
|
|
|
|
// Update add a new entry for wifi interface in UCI Configuration
|
|
func (wi *UCIWirelessInterface) Update(uci *UCI) *Action {
|
|
wi.Delete(uci)
|
|
create := wi.Create(uci)
|
|
if create.ReturnCode != 0 {
|
|
return create
|
|
}
|
|
return uci.Commit()
|
|
}
|
|
|
|
// Scan starts a scan for wifi networks with this device
|
|
func (wi *UCIWirelessInterface) Scan() []*WifiCell {
|
|
devName := wi.GetSysDevName("")
|
|
|
|
wifi := NewWifiScanner(devName)
|
|
return wifi.Scan()
|
|
}
|
|
|
|
// Connect updates configuration to connect to the WifiCell
|
|
func (wi *UCIWirelessInterface) Connect(uci *UCI, cell *WifiCell, secret string) *Action {
|
|
wi.Ssid = cell.Ssid
|
|
wi.Bssid = cell.MacAddress
|
|
wi.Encryption = cell.Encryption
|
|
wi.Mode = "sta"
|
|
wi.Key = secret
|
|
res := wi.Update(uci)
|
|
if res.ReturnCode != 0 {
|
|
return res
|
|
}
|
|
return wi.Save(uci)
|
|
}
|