From 676121199d07f10a345d5f80a162834f325c9048 Mon Sep 17 00:00:00 2001 From: Matias Doyle Date: Thu, 9 Nov 2017 20:52:46 +0100 Subject: [PATCH] Initial version of STATUS command At the moment only returning a subset of the values you can get. That will come later. --- unixgram.go | 44 +++++++++++++++++++++++++++++++++++++------- unixgram_test.go | 34 ++++++++++++++++++++++++++++++++++ wpasupplicant.go | 25 +++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 7 deletions(-) diff --git a/unixgram.go b/unixgram.go index 90ab44f..2795f80 100644 --- a/unixgram.go +++ b/unixgram.go @@ -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 diff --git a/unixgram_test.go b/unixgram_test.go index 431bc4c..64006f3 100644 --- a/unixgram_test.go +++ b/unixgram_test.go @@ -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()) + } +} diff --git a/wpasupplicant.go b/wpasupplicant.go index 1152b44..5cd413c 100644 --- a/wpasupplicant.go +++ b/wpasupplicant.go @@ -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