diff --git a/packages/lime-system/files/usr/lib/lua/lime/wireless.lua b/packages/lime-system/files/usr/lib/lua/lime/wireless.lua index 7c55a9054..e65cfc8d2 100644 --- a/packages/lime-system/files/usr/lib/lua/lime/wireless.lua +++ b/packages/lime-system/files/usr/lib/lua/lime/wireless.lua @@ -30,11 +30,25 @@ end function wireless.scandevices() local devices = {} local uci = config.get_uci_cursor() - uci:foreach("wireless", "wifi-device", function(dev) devices[dev[".name"]] = dev end) + + uci:foreach("wireless", "wifi-device", function(dev) + local path = dev.path + if path then + local _, numberOfMatches = fs.glob("/sys/devices/"..path.."/ieee80211/phy*") + if numberOfMatches > 0 then + devices[dev[".name"]] = dev + else + utils.log("Skipping radio "..dev[".name"].." - hardware not found") + end + else + devices[dev[".name"]] = dev + end + end) local sorted_devices = {} for _, dev in pairs(devices) do - table.insert(sorted_devices, utils.indexFromName(dev[".name"])+1, dev) + local index = utils.indexFromName(dev[".name"]) or #sorted_devices + table.insert(sorted_devices, index+1, dev) end local band_2ghz_index = 0 diff --git a/packages/lime-system/tests/test_lime_wireless.lua b/packages/lime-system/tests/test_lime_wireless.lua index a4715d5c5..d57040727 100644 --- a/packages/lime-system/tests/test_lime_wireless.lua +++ b/packages/lime-system/tests/test_lime_wireless.lua @@ -121,6 +121,108 @@ describe('LiMe Wireless tests #wireless', function() end) + it('test mesh_ifaces() includes APUP peer interfaces', function() + uci:set('wireless', 'wlan0_mesh_foo', 'wifi-iface') + uci:set('wireless', 'wlan0_mesh_foo', 'mode', 'mesh') + uci:set('wireless', 'wlan0_mesh_foo', 'ifname', 'wlan0-mesh') + + uci:set('wireless', 'lm_wlan0_apup_radio0', 'wifi-iface') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'mode', 'ap') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'device', 'radio0') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'ifname', 'wlan0-apup') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'apup', '1') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'apup_peer_ifname_prefix', 'wlan0-peer') + + stub(utils, "unsafe_shell", function(cmd) + if cmd:match("ls /sys/class/net/") then + return "wlan0-apup\nwlan0-peer0\nwlan0-peer1\nwlan0-mesh\n" + end + return "" + end) + + local ifaces = wireless.mesh_ifaces() + assert.is.equal(3, #ifaces) + + local function contains(tbl, val) + for _, v in ipairs(tbl) do + if v == val then return true end + end + return false + end + + assert.is_true(contains(ifaces, 'wlan0-mesh')) + assert.is_true(contains(ifaces, 'wlan0-peer0')) + assert.is_true(contains(ifaces, 'wlan0-peer1')) + + utils.unsafe_shell:revert() + end) + + it('test scandevices() skips radio with missing hardware', function() + local fs = require 'nixio.fs' + stub(fs, "glob", function(_) + return {}, 0 + end) + + uci:set('wireless', 'radio0', 'wifi-device') + uci:set('wireless', 'radio0', 'band', '5g') + uci:set('wireless', 'radio0', 'path', 'pci0000:01/0000:01:00.0') + uci:commit('wireless') + + local devices = wireless.scandevices() + assert.is.equal(0, utils.tableLength(devices)) + + fs.glob:revert() + end) + + it('test scandevices() includes radio without path', function() + uci:set('wireless', 'radio0', 'wifi-device') + uci:set('wireless', 'radio0', 'band', '5g') + uci:commit('wireless') + iwinfo.fake.load_from_uci(uci) + + local devices = wireless.scandevices() + assert.is.equal(1, utils.tableLength(devices)) + assert.is.equal(0, devices['radio0']['.index']) + assert.is.equal('radio0', devices['radio0']['.name']) + end) + + it('test scandevices() includes radio with APUP interface configured', function() + local fs = require 'nixio.fs' + stub(fs, "glob", function(pattern) + if pattern:match("platform/ahb/18100000%.wmac/ieee80211/phy%*") then + return {"/sys/devices/platform/ahb/18100000.wmac/ieee80211/phy0"}, 1 + end + return {}, 0 + end) + + uci:set('wireless', 'radio0', 'wifi-device') + uci:set('wireless', 'radio0', 'type', 'mac80211') + uci:set('wireless', 'radio0', 'path', 'platform/ahb/18100000.wmac') + uci:set('wireless', 'radio0', 'band', '2g') + uci:set('wireless', 'radio0', 'channel', '11') + uci:set('wireless', 'radio0', 'htmode', 'HT20') + uci:set('wireless', 'radio0', 'disabled', '0') + + uci:set('wireless', 'lm_wlan0_apup_radio0', 'wifi-iface') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'mode', 'ap') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'device', 'radio0') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'ifname', 'wlan0-apup') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'apup', '1') + uci:set('wireless', 'lm_wlan0_apup_radio0', 'apup_peer_ifname_prefix', 'wlan0-peer') + + uci:commit('wireless') + iwinfo.fake.load_from_uci(uci) + + local devices = wireless.scandevices() + assert.is.equal(1, utils.tableLength(devices)) + assert.is.equal('radio0', devices['radio0']['.name']) + assert.is.equal('platform/ahb/18100000.wmac', devices['radio0'].path) + assert.is.equal(0, devices['radio0']['.index']) + assert.is.equal(0, devices['radio0'].per_band_index) + + fs.glob:revert() + end) + it('test configure() with distance', function() uci:set('wireless', 'radio0', 'wifi-device') uci:set('wireless', 'radio0', 'band', '5g') diff --git a/tests/test_lime_config_device.lua b/tests/test_lime_config_device.lua index 081aa377e..77b54f7b3 100644 --- a/tests/test_lime_config_device.lua +++ b/tests/test_lime_config_device.lua @@ -10,6 +10,7 @@ local test_utils = require 'tests.utils' config.log = function() end local uci +local snapshot -- to revert luassert stubs and spies local librerouter_board = test_utils.get_board('librerouter-v1') @@ -23,6 +24,19 @@ describe('LiMe Config tests', function() stub(network, "assert_interface_exists", function () return true end) stub(network, "_get_lower", function () return "wan" end) + -- Stub fs.glob to prevent wireless scandevices() from skipping radios + -- due to missing hardware in test environment (commit 45f0ee7d). + -- Preserves original glob for hardware detection module discovery, + -- otherwise openwrt_wan module is not found and WAN config fails. + local fs = require 'nixio.fs' + local original_glob = fs.glob + stub(fs, "glob", function(pattern) + if pattern:match("/ieee80211/phy%*") then + return {"phy0"}, 1 + end + return original_glob(pattern) + end) + -- copy openwrt first boot generated configs for _, config_name in ipairs({'network', 'wireless'}) do local fin = io.open('tests/devices/librerouter-v1/uci_config_' .. config_name, 'r') @@ -84,10 +98,12 @@ describe('LiMe Config tests', function() end) before_each('', function() + snapshot = assert:snapshot() uci = test_utils.setup_test_uci() end) after_each('', function() + snapshot:revert() test_utils.teardown_test_uci(uci) end) end)