luci-base: add getWirelessDevices() rpc method
authorJo-Philipp Wich <jo@mein.io>
Tue, 3 Sep 2019 14:49:25 +0000 (16:49 +0200)
committerJo-Philipp Wich <jo@mein.io>
Tue, 10 Sep 2019 13:28:16 +0000 (15:28 +0200)
The getWirelessDevices() method merges the results of the
network.wireless/status call with corresponding per-radio and
per-network iwinfo data.

This allows to simplify the client side network state model
implementation and saves extraneous rpc roundtrips to fetch
iwinfo data after discovering the wireless devices.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/root/usr/libexec/rpcd/luci

index e27149127c7748ec81b1996c952de0dc449715fa..e94e3f1f7458ab5ba91059a4288be0ae5279058b 100755 (executable)
@@ -274,6 +274,66 @@ local methods = {
                end
        },
 
+       getWirelessDevices = {
+               call = function(args)
+                       local ubus = require "ubus".connect()
+                       if not ubus then
+                               return { error = "Unable to establish ubus connection" }
+                       end
+
+                       local status = ubus:call("network.wireless", "status", {})
+                       if type(status) == "table" then
+                               local radioname, radiodata
+                               for radioname, radiodata in pairs(status) do
+                                       if type(radiodata) == "table" then
+                                               radiodata.iwinfo = ubus:call("iwinfo", "info", { device = radioname }) or {}
+                                               radiodata.iwinfo.bitrate     = nil
+                                               radiodata.iwinfo.bssid       = nil
+                                               radiodata.iwinfo.encryption  = nil
+                                               radiodata.iwinfo.mode        = nil
+                                               radiodata.iwinfo.quality     = nil
+                                               radiodata.iwinfo.quality_max = nil
+                                               radiodata.iwinfo.ssid        = nil
+
+                                               local iwdata = nil
+
+                                               if type(radiodata.interfaces) == "table" then
+                                                       local _, interfacedata
+                                                       for _, interfacedata in ipairs(radiodata.interfaces) do
+                                                               if type(interfacedata) == "table" and
+                                                                  type(interfacedata.ifname) == "string"
+                                                               then
+                                                                       local iwinfo = ubus:call("iwinfo", "info", { device = interfacedata.ifname })
+
+                                                                       iwdata = iwdata or iwinfo
+                                                                       interfacedata.iwinfo = iwinfo or {}
+                                                               end
+                                                       end
+                                               end
+
+                                               radiodata.iwinfo = {}
+
+                                               local _, k, v
+                                               for k, v in pairs(iwdata or ubus:call("iwinfo", "info", { device = radioname }) or {}) do
+                                                       if k ~= "bitrate" and k ~= "bssid" and k ~= "encryption" and
+                                                          k ~= "mode" and k ~= "quality" and k ~= "quality_max" and
+                                                          k ~= "ssid"
+                                                       then
+                                                               if type(v) == "table" then
+                                                                       radiodata.iwinfo[k] = json.parse(json.stringify(v))
+                                                               else
+                                                                       radiodata.iwinfo[k] = v
+                                                               end
+                                                       end
+                                               end
+                                       end
+                               end
+                       end
+
+                       return status
+               end
+       },
+
        getBoardJSON = {
                call = function(args)
                        local jsc = require "luci.jsonc"