owrt/wifi_scanner.go

127 lines
2.8 KiB
Go

package owrt
import (
"regexp"
"strings"
"time"
)
// NONE contains the string for "none"
const NONE = "none"
// WifiScanner gives access to al OpenWRT Wifi Scan operations
type WifiScanner struct {
exec Executor
iface string
Cells []*WifiCell
}
// NewWifiScanner return an UCI instance to interact with UCI
func NewWifiScanner(wIface string) *WifiScanner {
exec := &localExecutor{}
iface := wIface
Cells := []*WifiCell{}
return &WifiScanner{exec, iface, Cells}
}
// NewWifiWithExecutor returns a Wifi Instance an gives you the ability to provide
// a different command executor than the default one.
func NewWifiWithExecutor(exec Executor, wIface string) *WifiScanner {
return &WifiScanner{exec, wIface, nil}
}
func (w *WifiScanner) getEncryption(line string) string {
var enc string
if strings.Contains(line, "PSK") {
enc = "psk2"
} else if strings.Contains(line, NONE) {
enc = NONE
} else {
enc = "unkn"
}
return enc
}
func (w *WifiScanner) parseWifiCells(stdout string) int {
mac, ssid, enc := "", "", ""
encOff := false
macExpr := `([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])`
for _, line := range strings.Split(strings.TrimSuffix(stdout, "\n"), "\n") {
expr := regexp.MustCompile("^BSS")
if expr.MatchString(line) {
if len(mac) != 0 && len(ssid) != 0 && len(enc) == 0 {
enc = NONE
cell := NewWifiCell(ssid, mac, enc)
w.Cells = append(w.Cells, cell)
ssid, enc = "", ""
}
macRegexp := regexp.MustCompile(macExpr)
mac = macRegexp.FindString(line)
}
if strings.Contains(line, "SSID:") {
ssid = strings.Split(line, " ")[1]
ssid = strings.Trim(ssid, "\"")
//ssid = strings.Trim(ssid, " ")
if ssid == "" {
ssid = " "
}
}
if strings.Contains(line, "Encryption key:off") {
encOff = true
}
if strings.Contains(line, "Authentication suites") {
enc = w.getEncryption(line)
}
if len(mac) > 0 && len(ssid) > 0 && (len(enc) > 0 || encOff) {
if encOff {
enc = NONE
encOff = false
}
cell := NewWifiCell(ssid, mac, enc)
w.Cells = append(w.Cells, cell)
ssid, mac, enc = "", "", ""
}
}
return 0
}
// GetWifiCells retrieves all available wifi cells for a card !
func (w *WifiScanner) GetWifiCells() int {
var res *CommandResult
for try := 0; try != 20; try++ {
res = w.exec.Run("iw", w.iface, "scan")
if res.ReturnCode == 0 {
parsing := w.parseWifiCells(res.Stdout)
if parsing == 0 {
if len(w.Cells) == 0 {
return 242
}
}
return parsing
}
time.Sleep(time.Second * 2)
}
return res.ReturnCode
}
// GetCell retreives an WifiCell by SSID provided in parameter
func (w *WifiScanner) GetCell(ssid string) *WifiCell {
for _, v := range w.Cells {
if v.Ssid == ssid {
return v
}
}
return nil
}
// Scan retreives a list of available wifi cells
func (w *WifiScanner) Scan() []*WifiCell {
_ = w.GetWifiCells()
return w.Cells
}