From 735bc8d19e3812ddebdd445eeae50bef7f458bee Mon Sep 17 00:00:00 2001 From: Philippe Caseiro Date: Thu, 20 Sep 2018 10:59:11 +0200 Subject: [PATCH] Adding DHCP Client and new Wifi stack --- openwrt/dhcp_client.go | 38 ++++ openwrt/dhcp_client_test.go | 12 ++ openwrt/executor.go | 1 + openwrt/uci.go | 86 ++++----- openwrt/uci_struct.go | 19 -- openwrt/uci_struct_test.go | 11 -- openwrt/uci_test.go | 88 ++++++++- openwrt/wifi.go | 88 +++++++++ openwrt/wifi_cell.go | 78 ++++++-- openwrt/wifi_cell_test.go | 21 ++ openwrt/wifi_test.go | 370 ++++++++++++++++++++++++++++++++++++ 11 files changed, 715 insertions(+), 97 deletions(-) create mode 100644 openwrt/dhcp_client.go create mode 100644 openwrt/dhcp_client_test.go delete mode 100644 openwrt/uci_struct.go delete mode 100644 openwrt/uci_struct_test.go create mode 100644 openwrt/wifi.go create mode 100644 openwrt/wifi_cell_test.go create mode 100644 openwrt/wifi_test.go diff --git a/openwrt/dhcp_client.go b/openwrt/dhcp_client.go new file mode 100644 index 0000000..40c81f3 --- /dev/null +++ b/openwrt/dhcp_client.go @@ -0,0 +1,38 @@ +package openwrt + +// DhcpClient represents a dhcp client ... :) +type DhcpClient struct { + exec Executor + iface string +} + +// NewDhcpClient return an UCI instance to interact with UCI +func NewDhcpClient(netIface string) *DhcpClient { + exec := &localExecutor{} + iface := netIface + return &DhcpClient{exec, iface} +} + +// NewDhcpClientWithExecutor return an UCI instance to interact with UCI +func NewDhcpClientWithExecutor(netIface string, exe Executor) *DhcpClient { + exec := exe + iface := netIface + return &DhcpClient{exec, iface} +} + +// NewDhcpClient return an UCI instance to interact with UCI +//func NewDhcpClient(netIface string, exe Executor) *DhcpClient { +// var exec Executor +// if exe == nil { +// exec = &localExecutor{} +// } else { +// exec = exe +// } +// iface := netIface +// return &DhcpClient{exec, iface} +//} + +// AskForIP runs a dhclient ip request with udhcpc +func (dc *DhcpClient) AskForIP() *CommandResult { + return dc.exec.Run("udhcpc", "-i", dc.iface) +} diff --git a/openwrt/dhcp_client_test.go b/openwrt/dhcp_client_test.go new file mode 100644 index 0000000..b21ca7e --- /dev/null +++ b/openwrt/dhcp_client_test.go @@ -0,0 +1,12 @@ +package openwrt + +import "testing" + +func TestDhcpClientAskForIP(t *testing.T) { + uexec := createMockExecutor("", "", 0) + dhc := NewDhcpClientWithExecutor("wlan1", uexec) + res := dhc.AskForIP() + if res.ReturnCode != 0 { + t.Error("Error in DHCP Client !!") + } +} diff --git a/openwrt/executor.go b/openwrt/executor.go index 2c19fb7..71d3ae7 100644 --- a/openwrt/executor.go +++ b/openwrt/executor.go @@ -7,6 +7,7 @@ import ( "os/exec" ) +// Executor interface to describe command runners signature type Executor interface { Run(command string, params ...string) *CommandResult } diff --git a/openwrt/uci.go b/openwrt/uci.go index d02872f..c5d7429 100644 --- a/openwrt/uci.go +++ b/openwrt/uci.go @@ -1,10 +1,7 @@ package openwrt import ( - "bytes" "fmt" - "log" - "os/exec" "time" ) @@ -13,64 +10,63 @@ type Action struct { *CommandResult } +// UCI "Object" +type UCI struct { + exec Executor +} + +// NewUCI return an UCI instance to interact with UCI +func NewUCI() *UCI { + exec := &localExecutor{} + return &UCI{exec} +} + +// NewUCIWithExecutor returns a UCI Instance an gives you the ability to provide +// a different command executor than the default one. +func NewUCIWithExecutor(exec Executor) *UCI { + return &UCI{exec} +} + // uciRun, private method to run the UCI command -func uciRun(uciAction string, param string) *Action { +func (u *UCI) uciRun(uciAction string, param string) *Action { cmd := "uci" - res := run(cmd, uciAction, param) - return &Action{ - res, - } + res := u.exec.Run(cmd, uciAction, param) + return &Action{res} } -// UciAdd add an entry to UCI configuration, specify the Module and the value -func UciAdd(module string, name string) *Action { - actionRes := uciRun("add", fmt.Sprintf("%s %s", module, name)) - return actionRes +// Add add an entry to UCI configuration, specify the Module and the value +func (u *UCI) Add(module string, name string) *Action { + commandRes := u.exec.Run("uci add", module, name) + return &Action{commandRes} } -// UciDelete delete an entry from UCI configuration specify the entry name -func UciDelete(entry string) *Action { - return uciRun("delete", entry) +// Delete delete an entry from UCI configuration specify the entry name +func (u *UCI) Delete(entry string) *Action { + return u.uciRun("delete", entry) } -// UciSet set a value ton an UCI configuration entry -func UciSet(entry string, value string) *Action { - return uciRun("set", fmt.Sprintf("%s=%s", entry, value)) +// Set set a value ton an UCI configuration entry +func (u *UCI) Set(entry string, value string) *Action { + return u.uciRun("set", fmt.Sprintf("%s=%s", entry, value)) } -// UciCommit the recent actions to UCI -func UciCommit() *Action { - return uciRun("commit", "") +// Commit the recent actions to UCI +func (u *UCI) Commit() *Action { + return u.uciRun("commit", "") } -// UciReload reload uci configuration -func UciReload() *Action { - var out bytes.Buffer - var stderr bytes.Buffer - - exe := exec.Command("reload_config") - exe.Stdout = &out - exe.Stderr = &stderr - - err := exe.Run() - if err != nil { - fmt.Println(fmt.Sprint(err) + ": " + stderr.String()) - log.Fatal(err) - } +// Reload reload uci configuration +func (u *UCI) Reload() *Action { + cmdResult := u.exec.Run("reload_config") time.Sleep(5) - return &Action{ - &CommandResult{ - Stdout: out.String(), - ReturnCode: 0, - }, - } + return &Action{cmdResult} } -// UciAddWireless Create a new Wireless entry in UCI configuration -func UciAddWireless(name string) int { - res := UciAdd("wireless", name) - return res.ReturnCode +// AddWireless Create a new Wireless entry in UCI configuration +func (u *UCI) AddWireless(name string) *Action { + res := u.Add("wireless", name) + return res } diff --git a/openwrt/uci_struct.go b/openwrt/uci_struct.go deleted file mode 100644 index d440ae6..0000000 --- a/openwrt/uci_struct.go +++ /dev/null @@ -1,19 +0,0 @@ -package openwrt - -type UCI struct { - exec Executor -} - -func NewUCI() *UCI { - exec := &localExecutor{} - return &UCI{exec} -} - -func NewUCIWithExecutor(exec Executor) *UCI { - return &UCI{exec} -} - -func (u *UCI) Add(module string, name string) *Action { - commandRes := u.exec.Run("uci add", module, name) - return &Action{commandRes} -} diff --git a/openwrt/uci_struct_test.go b/openwrt/uci_struct_test.go deleted file mode 100644 index af25884..0000000 --- a/openwrt/uci_struct_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package openwrt - -import ( - "testing" -) - -func TestUCIStruct(t *testing.T) { - exec := createMockExecutor("", "", 1) - uci := NewUCIWithExecutor(exec) - uci.Add("wireless", "test") -} diff --git a/openwrt/uci_test.go b/openwrt/uci_test.go index 927884d..36418af 100644 --- a/openwrt/uci_test.go +++ b/openwrt/uci_test.go @@ -1,15 +1,91 @@ package openwrt import ( + "fmt" "testing" ) -func TestUciAdd(t *testing.T) { - - // Return 0 run ! - res := UciAdd("wireless", "test") +func TestUCIAdd(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + res := uci.Add("wireless", "test") if res.ReturnCode != 0 { - t.Error(res.Stderr) + t.Error("Bad Return Code !") + } + if res.Stdout != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stdout is not empty ...") + } + if res.Stderr != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stderr is not empty ...") + } +} + +func TestUCIDelete(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + res := uci.Delete("wireless.@wifi-iface[1]") + if res.ReturnCode != 0 { + t.Error("Bad Return Code !") + } + if res.Stdout != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stdout is not empty ...") + } + if res.Stderr != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stderr is not empty ...") + } +} + +func TestUCISet(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + res := uci.Set("wireless.@wifi-iface[1].network", "OrionNetwork") + if res.ReturnCode != 0 { + t.Error("Bad Return Code !") + } + if res.Stdout != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stdout is not empty ...") + } + if res.Stderr != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stderr is not empty ...") + } +} + +func TestUCICommit(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + res := uci.Commit() + if res.ReturnCode != 0 { + t.Error("Bad Return Code !") + } + if res.Stdout != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stdout is not empty ...") + } + if res.Stderr != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stderr is not empty ...") + } +} + +func TestUCIReload(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + res := uci.Reload() + if res.ReturnCode != 0 { + t.Error("Bad Return Code !") + } + if res.Stdout != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stdout is not empty ...") + } + if res.Stderr != "" { + fmt.Printf("[%s] - ", res.Stdout) + t.Error("Stderr is not empty ...") } - } diff --git a/openwrt/wifi.go b/openwrt/wifi.go new file mode 100644 index 0000000..97174d7 --- /dev/null +++ b/openwrt/wifi.go @@ -0,0 +1,88 @@ +package openwrt + +import ( + "log" + "strings" + "time" +) + +// Wifi gives access to al OpenWRT Wifi operations +type Wifi struct { + exec Executor + iface string + Cells []*WifiCell +} + +// NewWifi return an UCI instance to interact with UCI +func NewWifi(wIface string) *Wifi { + exec := &localExecutor{} + iface := wIface + return &Wifi{exec, iface, nil} +} + +// 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) *Wifi { + return &Wifi{exec, wIface, nil} +} + +// GetWifiCells retrieves all availabe wifi cells for a card ! +func (w *Wifi) GetWifiCells() int { + res := w.exec.Run("iwinfo", w.iface, "scan") + if res.ReturnCode != 0 { + log.Fatal(res.Stderr) + return res.ReturnCode + } + + for res.Stdout == "Scanning not possible" { + time.Sleep(1) + res := w.exec.Run("iwinfo", w.iface, "scan") + if res.ReturnCode != 0 { + log.Fatal(res.Stderr) + return res.ReturnCode + } + } + + new := false + mac := "" + ssid := "" + enc := "" + for _, line := range strings.Split(strings.TrimSuffix(res.Stdout, "\n"), "\n") { + if strings.HasPrefix(line, "Cell") && new == false { + new = true + mac = strings.Split(line, " ")[4] + } + if strings.Contains(line, "ESSID:") { + ssid = strings.Split(line, " ")[1] + ssid = strings.Trim(ssid, "\"") + } + if strings.Contains(line, "Encryption:") { + if strings.Contains(line, "WPA2 PSK") { + enc = "psk" + } else if strings.Contains(line, "none") { + enc = "none" + } else { + enc = "unkn" + } + } + if len(mac) > 0 && len(ssid) > 0 && len(enc) > 0 { + cell := NewWifiCell(ssid, mac, enc) + w.Cells = append(w.Cells, cell) + ssid = "" + mac = "" + enc = "" + new = false + } + } + return 0 +} + +// GetCell retreives an WifiCell by SSID provided in parameter +func (w *Wifi) GetCell(ssid string) *WifiCell { + for _, v := range w.Cells { + if v.Ssid == ssid { + return v + } + } + return nil +} diff --git a/openwrt/wifi_cell.go b/openwrt/wifi_cell.go index a6ac91f..785c1f5 100644 --- a/openwrt/wifi_cell.go +++ b/openwrt/wifi_cell.go @@ -1,31 +1,77 @@ package openwrt -import ( - "fmt" - "strings" -) +import "time" // WifiCell reprensents wifi network Cell type WifiCell struct { - // The SSID - Ssid string - // The cell mac adress - MacAdress string + Ssid string + MacAdress string + Encryption string } // NewWifiCell returns a new WifiCell object -func NewWifiCell(ssid string, mac string) *WifiCell { +func NewWifiCell(ssid string, mac string, encrypt string) *WifiCell { return &WifiCell{ - Ssid: ssid, - MacAdress: mac, + Ssid: ssid, + MacAdress: mac, + Encryption: encrypt, } } -// GetWifiCells retrieves all availabe wifi cells for a card ! -func GetWifiCells(iface string) { - res := run("iwinfo", iface, "scan") - for _, line := range strings.Split(strings.TrimSuffix(res.Stdout, "\n"), "\n") { - fmt.Println(line) +// Connect to wifi Cell +func (cell *WifiCell) Connect(uci *UCI, secret string) *Action { + delRes := uci.Delete("wireless.@wifi-iface[1]") + if delRes.ReturnCode != 0 { + return delRes + } + addRes := uci.AddWireless("wifi-iface") + if addRes.ReturnCode != 0 { + return addRes } + setRes := uci.Set("wireless.@wifi-iface[1].network", "PyxisNetwork") + if setRes.ReturnCode != 0 { + return setRes + } + + setRes = uci.Set("wireless.@wifi-iface[1].ssid", cell.Ssid) + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Set("wireless.@wifi-iface[1].encryption", "psk2") + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Set("wireless.@wifi-iface[1].device", "radio1") + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Set("wireless.@wifi-iface[1].mode", "sta") + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Set("wireless.@wifi-iface[1].bssid", cell.MacAdress) + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Set("wireless.@wifi-iface[1].key", secret) + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Commit() + if setRes.ReturnCode != 0 { + return setRes + } + setRes = uci.Reload() + if setRes.ReturnCode != 0 { + return setRes + } + time.Sleep(20) + return &Action{ + &CommandResult{ + Stdout: "", + Stderr: "", + ReturnCode: 0, + }, + } } diff --git a/openwrt/wifi_cell_test.go b/openwrt/wifi_cell_test.go new file mode 100644 index 0000000..c54da57 --- /dev/null +++ b/openwrt/wifi_cell_test.go @@ -0,0 +1,21 @@ +package openwrt + +import "testing" + +func TestWifiCellConnection(t *testing.T) { + uexec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(uexec) + + cellList := `Cell 40 - Address: 68:A3:78:6E:D9:24 + ESSID: "PyxisWifi" + Mode: Master Channel: 3 + Signal: -90 dBm Quality: 20/70 + Encryption: WPA2 PSK (CCMP)` + + exec := createMockExecutor(cellList, "", 0) + wifi := NewWifiWithExecutor(exec, "wlan1") + _ = wifi.GetWifiCells() + + cell := wifi.GetCell("PyxisWifi") + cell.Connect(uci, "secret") +} diff --git a/openwrt/wifi_test.go b/openwrt/wifi_test.go new file mode 100644 index 0000000..f1e32c7 --- /dev/null +++ b/openwrt/wifi_test.go @@ -0,0 +1,370 @@ +package openwrt + +import ( + "fmt" + "testing" +) + +// Test GestWifiCells method with 3 Cells +func TestGetWifiCells(t *testing.T) { + cellList := `Cell 40 - Address: 68:A3:78:6E:D9:24 + ESSID: "PyxisWifi" + Mode: Master Channel: 3 + Signal: -90 dBm Quality: 20/70 + Encryption: none + +Cell 41 - Address: B0:39:56:92:59:E2 + ESSID: "NET17" + Mode: Master Channel: 4 + Signal: -88 dBm Quality: 22/70 + Encryption: WPA2 PSK (CCMP) + +Cell 42 - Address: 0C:F4:D5:16:AA:18 + ESSID: "DIJON-METROPOLE-WIFI" + Mode: Master Channel: 13 + Signal: -90 dBm Quality: 20/70 + Encryption: none` + + exec := createMockExecutor(cellList, "", 0) + wifi := NewWifiWithExecutor(exec, "wlan1") + _ = wifi.GetWifiCells() + if len(wifi.Cells) != 3 { + fmt.Printf("Size of wifi.Cells is %d and not 3 !!!\n", len(wifi.Cells)) + t.Error("Cell list is empty ... This can not append !! Fix your code Dummy !") + } + if g, e := wifi.Cells[0].Ssid, "PyxisWifi"; g != e { + t.Errorf("The first Cell have a bad SSID !\n %s is expected and we have %s", e, g) + } + + if g, e := wifi.Cells[0].MacAdress, "68:A3:78:6E:D9:24"; g != e { + t.Errorf("The first Cell have a bad MAC !\n %s is expected and we have %s", e, g) + } + + if g, e := wifi.Cells[0].Encryption, "none"; g != e { + t.Errorf("The first Cell have a bad Encryption!\n %s is expected and we have %s", e, g) + } + + if g, e := wifi.Cells[1].Encryption, "psk"; g != e { + t.Errorf("The second Cell have a bad Encryption!\n %s is expected and we have %s", e, g) + } + + if g, e := wifi.Cells[2].MacAdress, "0C:F4:D5:16:AA:18"; g != e { + t.Errorf("The last Cell have a bad MAC !\n %s is expected and we have %s", e, g) + } +} + +// Test GestWifiCells method with empty list +func TestGetWifiCellsEmpty(t *testing.T) { + exec := createMockExecutor("", "", 0) + wifi := NewWifiWithExecutor(exec, "wlan1") + _ = wifi.GetWifiCells() + if len(wifi.Cells) != 0 { + fmt.Printf("Size of wifi.Cells is %d and not 0 !!!\n", len(wifi.Cells)) + t.Error("Cell list is empty ... This can not append !! Fix your code Dummy !") + } +} + +// Test GestWifiCells method with 3 Cells +func TestGetWifiCellsLarge(t *testing.T) { + cellList := `Cell 01 - Address: 0C:8D:DB:C4:A0:34 + ESSID: "pfPauvres" + Mode: Master Channel: 11 + Signal: -50 dBm Quality: 60/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 02 - Address: 40:5A:9B:ED:BA:F0 + ESSID: "Cadoles" + Mode: Master Channel: 6 + Signal: -36 dBm Quality: 70/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 03 - Address: A0:04:60:B2:8A:C8 + ESSID: "Cadoles Formations (N)" + Mode: Master Channel: 13 + Signal: -32 dBm Quality: 70/70 + Encryption: WPA2 PSK (CCMP) + +Cell 04 - Address: B0:39:56:D8:38:ED + ESSID: "Frate Dijon EXT" + Mode: Master Channel: 11 + Signal: -57 dBm Quality: 53/70 + Encryption: WPA2 PSK (CCMP) + +Cell 05 - Address: 00:A6:CA:10:DF:00 + ESSID: unknown + Mode: Master Channel: 6 + Signal: -80 dBm Quality: 30/70 + Encryption: WPA2 802.1X (CCMP) + +Cell 06 - Address: AC:84:C9:2F:59:6E + ESSID: "Livebox-596a" + Mode: Master Channel: 1 + Signal: -62 dBm Quality: 48/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 07 - Address: 00:A6:CA:10:DF:01 + ESSID: "EFF-Mobility" + Mode: Master Channel: 6 + Signal: -74 dBm Quality: 36/70 + Encryption: WPA2 PSK (CCMP) + +Cell 08 - Address: A0:1B:29:BE:98:26 + ESSID: "Livebox-9822" + Mode: Master Channel: 6 + Signal: -81 dBm Quality: 29/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 09 - Address: 7C:26:64:66:CC:44 + ESSID: "Livebox-32c8" + Mode: Master Channel: 1 + Signal: -74 dBm Quality: 36/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 10 - Address: 00:A6:CA:10:DF:02 + ESSID: "Keo-HotSpot" + Mode: Master Channel: 6 + Signal: -79 dBm Quality: 31/70 + Encryption: none + +Cell 11 - Address: 7E:26:64:66:CC:44 + ESSID: "orange" + Mode: Master Channel: 1 + Signal: -73 dBm Quality: 37/70 + Encryption: none + +Cell 12 - Address: 3C:52:82:FC:5E:21 + ESSID: "DIRECT-20-HP DeskJet 3630 series" + Mode: Master Channel: 6 + Signal: -78 dBm Quality: 32/70 + Encryption: WPA2 PSK (CCMP) + +Cell 13 - Address: E4:9E:12:8B:EF:73 + ESSID: "Freebox-8BEF72" + Mode: Master Channel: 9 + Signal: -79 dBm Quality: 31/70 + Encryption: WPA2 PSK (CCMP) + +Cell 14 - Address: 40:4A:03:05:D2:68 + ESSID: "ZyXEL" + Mode: Master Channel: 11 + Signal: -71 dBm Quality: 39/70 + Encryption: WPA2 PSK (CCMP) + +Cell 15 - Address: 5C:C3:07:7E:39:D4 + ESSID: "pfP Xa" + Mode: Master Channel: 1 + Signal: -65 dBm Quality: 45/70 + Encryption: WPA2 PSK (CCMP) + +Cell 16 - Address: AC:84:C9:1D:C6:7C + ESSID: "Frate Djon" + Mode: Master Channel: 1 + Signal: -79 dBm Quality: 31/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 17 - Address: 00:17:33:9F:4D:80 + ESSID: "NEUF_4D7C" + Mode: Master Channel: 11 + Signal: -83 dBm Quality: 27/70 + Encryption: WPA PSK (TKIP, CCMP) + +Cell 18 - Address: A2:17:33:9F:4D:81 + ESSID: "SFR WiFi FON" + Mode: Master Channel: 11 + Signal: -85 dBm Quality: 25/70 + Encryption: none + +Cell 19 - Address: BC:F6:85:FE:6D:46 + ESSID: "Dlink" + Mode: Master Channel: 12 + Signal: -70 dBm Quality: 40/70 + Encryption: WPA2 PSK (CCMP) + +Cell 20 - Address: 30:7C:B2:D1:0B:0D + ESSID: "Livebox-0b09" + Mode: Master Channel: 11 + Signal: -81 dBm Quality: 29/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 21 - Address: A2:17:33:9F:4D:83 + ESSID: "SFR WiFi Mobile" + Mode: Master Channel: 11 + Signal: -85 dBm Quality: 25/70 + Encryption: WPA2 802.1X (CCMP) + +Cell 22 - Address: 90:4D:4A:F7:B9:70 + ESSID: "Livebox-B970" + Mode: Master Channel: 11 + Signal: -84 dBm Quality: 26/70 + Encryption: WPA2 PSK (CCMP) + +Cell 23 - Address: 90:4D:4A:F7:B9:71 + ESSID: "orange" + Mode: Master Channel: 11 + Signal: -89 dBm Quality: 21/70 + Encryption: none + +Cell 24 - Address: 00:22:6B:86:5B:71 + ESSID: "linksys" + Mode: Master Channel: 11 + Signal: -86 dBm Quality: 24/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 25 - Address: 68:A3:78:6E:D9:25 + ESSID: "FreeWifi_secure" + Mode: Master Channel: 3 + Signal: -86 dBm Quality: 24/70 + Encryption: WPA2 802.1X (TKIP, CCMP) + +Cell 26 - Address: 6C:38:A1:62:1B:28 + ESSID: "Bbox-1B7889A9" + Mode: Master Channel: 1 + Signal: -90 dBm Quality: 20/70 + Encryption: mixed WPA/WPA2 PSK (CCMP) + +Cell 27 - Address: 78:81:02:5E:B7:14 + ESSID: "Livebox-B714" + Mode: Master Channel: 6 + Signal: -86 dBm Quality: 24/70 + Encryption: WPA2 PSK (CCMP) + +Cell 28 - Address: F4:CA:E5:98:3B:DC + ESSID: "Freebox-5D2400" + Mode: Master Channel: 11 + Signal: -84 dBm Quality: 26/70 + Encryption: WPA PSK (CCMP) + +Cell 29 - Address: 8C:DC:D4:93:69:17 + ESSID: "HP-Print-17-Photosmart 5520" + Mode: Master Channel: 11 + Signal: -87 dBm Quality: 23/70 + Encryption: none + +Cell 30 - Address: 44:CE:7D:20:5C:A4 + ESSID: "SFR_5CA0" + Mode: Master Channel: 6 + Signal: -86 dBm Quality: 24/70 + Encryption: WPA PSK (TKIP, CCMP) + +Cell 31 - Address: F4:CA:E5:98:3B:DE + ESSID: "FreeWifi_secure" + Mode: Master Channel: 11 + Signal: -72 dBm Quality: 38/70 + Encryption: WPA2 802.1X (TKIP, CCMP) + +Cell 32 - Address: 70:0B:01:C0:B3:E0 + ESSID: "Livebox-B3E0" + Mode: Master Channel: 11 + Signal: -80 dBm Quality: 30/70 + Encryption: WPA2 PSK (CCMP) + +Cell 33 - Address: D2:CE:7D:20:5C:A7 + ESSID: "SFR WiFi Mobile" + Mode: Master Channel: 6 + Signal: -85 dBm Quality: 25/70 + Encryption: WPA2 802.1X (CCMP) + +Cell 34 - Address: 68:A3:78:0D:B6:51 + ESSID: "Freebox-0DB650" + Mode: Master Channel: 1 + Signal: -92 dBm Quality: 18/70 + Encryption: WPA2 PSK (CCMP) + +Cell 35 - Address: F8:AB:05:1D:6A:E0 + ESSID: "Bbox-8CE43C68" + Mode: Master Channel: 6 + Signal: -88 dBm Quality: 22/70 + Encryption: mixed WPA/WPA2 PSK (CCMP) + +Cell 36 - Address: F4:CA:E5:98:3B:DD + ESSID: "FreeWifi" + Mode: Master Channel: 11 + Signal: -87 dBm Quality: 23/70 + Encryption: none + +Cell 37 - Address: 14:0C:76:79:C0:D9 + ESSID: "freebox_ZFSFUA" + Mode: Master Channel: 4 + Signal: -88 dBm Quality: 22/70 + Encryption: WPA PSK (TKIP, CCMP) + +Cell 38 - Address: 68:15:90:36:63:60 + ESSID: "Livebox-6360" + Mode: Master Channel: 1 + Signal: -81 dBm Quality: 29/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 39 - Address: 64:7C:34:29:2B:7C + ESSID: "Bbox-D646CB51" + Mode: Master Channel: 1 + Signal: -90 dBm Quality: 20/70 + Encryption: mixed WPA/WPA2 PSK (CCMP) + +Cell 40 - Address: 68:A3:78:6E:D9:24 + ESSID: "FreeWifi" + Mode: Master Channel: 3 + Signal: -90 dBm Quality: 20/70 + Encryption: none + +Cell 41 - Address: B0:39:56:92:59:E2 + ESSID: "NETGEAR17" + Mode: Master Channel: 4 + Signal: -88 dBm Quality: 22/70 + Encryption: WPA2 PSK (CCMP) + +Cell 42 - Address: 0C:F4:D5:16:AA:18 + ESSID: "DIJON-METROPOLE-WIFI" + Mode: Master Channel: 13 + Signal: -90 dBm Quality: 20/70 + Encryption: none + +Cell 43 - Address: D2:CE:7D:20:5C:A5 + ESSID: "SFR WiFi FON" + Mode: Master Channel: 6 + Signal: -81 dBm Quality: 29/70 + Encryption: none + +Cell 44 - Address: 34:27:92:42:CD:72 + ESSID: "Freebox-42CD71" + Mode: Master Channel: 8 + Signal: -88 dBm Quality: 22/70 + Encryption: WPA2 PSK (CCMP) + +Cell 45 - Address: 72:5D:51:78:4C:87 + ESSID: "SFR WiFi FON" + Mode: Master Channel: 11 + Signal: -87 dBm Quality: 23/70 + Encryption: none + +Cell 46 - Address: 68:A3:78:6E:D9:23 + ESSID: "Freebox-6ED922" + Mode: Master Channel: 3 + Signal: -76 dBm Quality: 34/70 + Encryption: WPA2 PSK (CCMP) + +Cell 47 - Address: 00:19:70:4F:DE:F2 + ESSID: "Livebox-45cc" + Mode: Master Channel: 6 + Signal: -78 dBm Quality: 32/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + +Cell 48 - Address: AC:84:C9:CC:AE:90 + ESSID: "Livebox-AE90" + Mode: Master Channel: 11 + Signal: -81 dBm Quality: 29/70 + Encryption: WPA2 PSK (CCMP) + +Cell 49 - Address: 00:07:7D:89:81:B0 + ESSID: "orange" + Mode: Master Channel: 6 + Signal: -85 dBm Quality: 25/70 + Encryption: none` + + exec := createMockExecutor(cellList, "", 0) + wifi := NewWifiWithExecutor(exec, "wlan1") + _ = wifi.GetWifiCells() + if len(wifi.Cells) != 49 { + fmt.Printf("Size of wifi.Cells is %d and not 49 !!!\n", len(wifi.Cells)) + t.Error("Cell list is empty ... This can not append !! Fix your code Dummy !") + } +}