Initial version of STATUS command

At the moment only returning a subset of the values you can get. That
will come later.
This commit is contained in:
Matias Doyle 2017-11-09 20:52:46 +01:00
parent 763b1685df
commit 676121199d
3 changed files with 96 additions and 7 deletions

View File

@ -330,6 +330,15 @@ func (uc *unixgramConn) ScanResults() ([]ScanResult, []error) {
return parseScanResults(bytes.NewBuffer(resp))
}
func (uc *unixgramConn) Status() (StatusResult, error) {
resp, err := uc.cmd("STATUS")
if err != nil {
return nil, err
}
return parseStatusResults(bytes.NewBuffer(resp))
}
func (uc *unixgramConn) ListNetworks() ([]ConfiguredNetwork, error) {
resp, err := uc.cmd("LIST_NETWORKS")
if err != nil {
@ -360,10 +369,7 @@ func parseListNetworksResult(resp io.Reader) (res []ConfiguredNetwork, err error
return nil, &ParseError{}
}
fmt.Println("Listing networks")
networkIDCol, ssidCol, bssidCol, flagsCol, maxCol := -1, -1, -1, -1, -1
fmt.Println(strings.Split(s.Text(), " / "))
for n, col := range strings.Split(s.Text(), " / ") {
switch col {
case "network id":
@ -379,12 +385,9 @@ func parseListNetworksResult(resp io.Reader) (res []ConfiguredNetwork, err error
maxCol = n
}
fmt.Println(networkIDCol)
for s.Scan() {
ln := s.Text()
fields := strings.Split(ln, "\t")
fmt.Println(fields)
if len(fields) < maxCol {
return nil, &ParseError{Line: ln}
}
@ -417,8 +420,35 @@ func parseListNetworksResult(resp io.Reader) (res []ConfiguredNetwork, err error
bssid: bssid,
flags: flags,
})
}
// fmt.Println(res)
return res, nil
}
func parseStatusResults(resp io.Reader) (StatusResult, error) {
s := bufio.NewScanner(resp)
res := &statusResult{}
for s.Scan() {
ln := s.Text()
fields := strings.Split(ln, "=")
if len(fields) != 2 {
continue
}
switch fields[0] {
case "wpa_state":
res.wpaState = fields[1]
case "key_mgmt":
res.keyMgmt = fields[1]
case "ip_address":
res.ipAddr = fields[1]
case "ssid":
res.ssid = fields[1]
case "address":
res.address = fields[1]
}
}
return res, nil

View File

@ -131,3 +131,37 @@ func TestParseScanResults(t *testing.T) {
}
}
}
func TestParseStatusResults(t *testing.T) {
testData := "bssid=02:00:01:02:03:04\n" +
"ssid=test network\n" +
"pairwise_cipher=CCMP\n" +
"group_cipher=CCMP\n" +
"key_mgmt=WPA-PSK\n" +
"wpa_state=COMPLETED\n" +
"ip_address=192.168.1.21\n" +
"Supplicant PAE state=AUTHENTICATED\n" +
"suppPortStatus=Authorized\n" +
"EAP state=SUCCESS"
res, err := parseStatusResults(bytes.NewBufferString(testData))
if err != nil {
t.Errorf("Error parsing status result %t", err)
}
if res.WPAState() != "COMPLETED" {
t.Errorf("WPAState was not COMPLETED. Was %s", res.WPAState())
}
if res.IPAddr() != "192.168.1.21" {
t.Errorf("IPAddr was not 192.168.1.21. Was %s", res.IPAddr())
}
if res.KeyMgmt() != "WPA-PSK" {
t.Errorf("KeyMgmt was not WPA-PSK. Was %s", res.KeyMgmt())
}
if res.Address() != "" {
t.Errorf("Address should be empty. Was %s", res.Address())
}
}

View File

@ -140,6 +140,28 @@ func (r *configuredNetwork) BSSID() string { return r.bssid }
func (r *configuredNetwork) SSID() string { return r.ssid }
func (r *configuredNetwork) Flags() []string { return r.flags }
type StatusResult interface {
WPAState() string
KeyMgmt() string
IPAddr() string
SSID() string
Address() string
}
type statusResult struct {
wpaState string
keyMgmt string
ipAddr string
ssid string
address string
}
func (s *statusResult) WPAState() string { return s.wpaState }
func (s *statusResult) KeyMgmt() string { return s.keyMgmt }
func (s *statusResult) IPAddr() string { return s.ipAddr }
func (s *statusResult) SSID() string { return s.ssid }
func (s *statusResult) Address() string { return s.address }
type WPAEvent struct {
Event string
Arguments map[string]string
@ -200,6 +222,9 @@ type Conn interface {
// ListNetworks returns the currently configured networks.
ListNetworks() ([]ConfiguredNetwork, error)
// Status returns current wpa_supplicant status
Status() (StatusResult, error)
// Scan triggers a new scan. Returns error if the wpa_supplicant does not
// return OK.
Scan() error