127 lines
2.8 KiB
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
|
||
|
}
|