375 lines
12 KiB
Lua
375 lines
12 KiB
Lua
------------------------------------
|
|
-- This is the network controller --
|
|
------------------------------------
|
|
|
|
-- Awesome Libs
|
|
local abutton = require("awful.button")
|
|
local awidget = require("awful.widget")
|
|
local dpi = require("beautiful").xresources.apply_dpi
|
|
local gtable = require("gears").table
|
|
local gfilesystem = require("gears").filesystem
|
|
local gcolor = require("gears").color
|
|
local lgi = require("lgi")
|
|
local wibox = require("wibox")
|
|
local base = require("wibox.widget.base")
|
|
local NM = lgi.NM
|
|
|
|
-- Third party libs
|
|
local dbus_proxy = require("src.lib.lua-dbus_proxy.src.dbus_proxy")
|
|
|
|
-- Own libs
|
|
local ap_form = require("src.modules.network_controller.ap_form")
|
|
local cm = require("src.modules.context_menu.init")
|
|
|
|
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/network/"
|
|
|
|
local access_point = { mt = {} }
|
|
|
|
local function flags_to_security(flags, wpa_flags, rsn_flags)
|
|
local str = ""
|
|
if flags == 1 and wpa_flags == 0 and rsn_flags == 0 then
|
|
str = str .. " WEP"
|
|
end
|
|
if wpa_flags ~= 0 then
|
|
str = str .. " WPA1"
|
|
end
|
|
if not rsn_flags ~= 0 then
|
|
str = str .. " WPA2"
|
|
end
|
|
if wpa_flags == 512 or rsn_flags == 512 then
|
|
str = str .. " 802.1X"
|
|
end
|
|
|
|
return (str:gsub("^%s", ""))
|
|
end
|
|
|
|
function access_point:get_access_point_connections(ssid)
|
|
local cn = {}
|
|
|
|
local connections = self.NetworkManagerSettings:ListConnections()
|
|
for _, connection_path in ipairs(connections) do
|
|
local NetworkManagerSettingsConnection = dbus_proxy.Proxy:new {
|
|
bus = dbus_proxy.Bus.SYSTEM,
|
|
name = "org.freedesktop.NetworkManager",
|
|
interface = "org.freedesktop.NetworkManager.Settings.Connection",
|
|
path = connection_path
|
|
}
|
|
|
|
if NetworkManagerSettingsConnection.Filename:find(ssid) then
|
|
table.insert(cn, NetworkManagerSettingsConnection)
|
|
end
|
|
end
|
|
|
|
return cn
|
|
end
|
|
|
|
function access_point:create_profile(ap, password, auto_connect)
|
|
local s_wsec = {}
|
|
local security = flags_to_security(ap.Flags, ap.WpaFlags, ap.RsnFlags)
|
|
if security ~= "" then
|
|
if security:match("WPA") then
|
|
s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "wpa-psk")
|
|
s_wsec["auth-alg"] = lgi.GLib.Variant("s", "open")
|
|
s_wsec["psk"] = lgi.GLib.Variant("s", password)
|
|
else
|
|
s_wsec["key-mgmt"] = lgi.GLib.Variant("s", "None")
|
|
s_wsec["wep-key-type"] = lgi.GLib.Variant("s", NM.WepKeyType.PASSPHRASE)
|
|
s_wsec["wep-key0"] = lgi.GLib.Variant("s", password)
|
|
end
|
|
end
|
|
|
|
return {
|
|
["connection"] = {
|
|
-- ["interface-name"] = lgi.GLib.Variant("s", ap.device_interface),
|
|
["uuid"] = lgi.GLib.Variant("s", string.gsub('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', '[xy]', function(c)
|
|
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
|
return string.format('%x', v)
|
|
end)),
|
|
["id"] = lgi.GLib.Variant("s", NM.utils_ssid_to_utf8(ap.Ssid)),
|
|
["type"] = lgi.GLib.Variant("s", "802-11-wireless"),
|
|
["autoconnect"] = lgi.GLib.Variant("b", auto_connect),
|
|
},
|
|
["ipv4"] = {
|
|
["method"] = lgi.GLib.Variant("s", "auto")
|
|
},
|
|
["ipv6"] = {
|
|
["method"] = lgi.GLib.Variant("s", "auto"),
|
|
},
|
|
["802-11-wireless"] = {
|
|
["mode"] = lgi.GLib.Variant("s", "infrastructure"),
|
|
},
|
|
["802-11-wireless-security"] = s_wsec
|
|
}
|
|
end
|
|
|
|
function access_point:disconnect()
|
|
self.NetworkManager:DeactivateConnection(self.NetworkManagerDevice.ActiveConnection)
|
|
end
|
|
|
|
function access_point:connect(ap, password, auto_connect)
|
|
local connections = self:get_access_point_connections(NM.utils_ssid_to_utf8(ap.Ssid))
|
|
local profile = self:create_profile(self.NetworkManagerAccessPoint, password, auto_connect)
|
|
|
|
if #connections == 0 then
|
|
self.NetworkManager:AddAndActivateConnectionAsync(function(proxy, context, success, fail)
|
|
if fail ~= nil then
|
|
print("Error: " .. tostring(fail), tostring(fail.code))
|
|
self:emit_signal("NetworkManager::failed", tostring(fail), tostring(fail.code))
|
|
return
|
|
end
|
|
|
|
self:emit_signal("NetworkManager::connected", success)
|
|
end, { call_id = "my-id" }, profile, self.NetworkManagerDevice.object_path,
|
|
self.NetworkManagerAccessPoint.object_path)
|
|
--88ALYLNxo9Kk*RwRxMfN
|
|
else
|
|
connections[1]:Update(profile)
|
|
self.NetworkManager:ActivateConnectionAsync(function(proxy, context, success, failure)
|
|
if failure then
|
|
self:emit_signal("NM::AccessPointFailed", tostring(failure))
|
|
return
|
|
end
|
|
|
|
self:emit_signal("NM::AccessPointConnected", NM.utils_ssid_to_utf8(ap.Ssid))
|
|
end,
|
|
{ call_id = "my-id" }, connections[1].object_path, self.NetworkManagerDevice.object_path,
|
|
self.NetworkManagerAccessPoint.object_path)
|
|
end
|
|
end
|
|
|
|
function access_point:toggle_connection(ap, password, auto_connect)
|
|
if self:is_ap_active(ap) then
|
|
self:disconnect()
|
|
else
|
|
self:connect(ap, password, auto_connect)
|
|
end
|
|
end
|
|
|
|
function access_point:is_ap_active(ap)
|
|
return ap.object_path == self.NetworkManagerDeviceWireless.ActiveAccessPoint
|
|
end
|
|
|
|
function access_point.new(args)
|
|
args = args or {}
|
|
|
|
if not args.NetworkManagerAccessPoint then return end
|
|
|
|
local ssid_text = awidget.inputbox {
|
|
text = NM.utils_ssid_to_utf8(args.NetworkManagerAccessPoint.Ssid) or
|
|
args.NetworkManagerAccessPoint.hw_address or "Unknown",
|
|
halign = "left",
|
|
valign = "center",
|
|
}
|
|
|
|
local ret = base.make_widget_from_value(wibox.widget {
|
|
{
|
|
{
|
|
{
|
|
{
|
|
{
|
|
image = gcolor.recolor_image(
|
|
icondir .. "wifi-strength-" .. math.floor(args.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
|
Theme_config.network_manager.access_point.icon_color),
|
|
id = "icon",
|
|
resize = true,
|
|
valign = "center",
|
|
halign = "center",
|
|
forced_width = dpi(24),
|
|
forced_height = dpi(24),
|
|
widget = wibox.widget.imagebox
|
|
},
|
|
id = "icon_container",
|
|
strategy = "max",
|
|
width = dpi(24),
|
|
height = dpi(24),
|
|
widget = wibox.container.constraint
|
|
},
|
|
{
|
|
{
|
|
ssid_text,
|
|
widget = wibox.container.constraint,
|
|
strategy = "exact",
|
|
width = dpi(300),
|
|
id = "alias"
|
|
},
|
|
width = dpi(260),
|
|
height = dpi(40),
|
|
strategy = "max",
|
|
widget = wibox.container.constraint
|
|
},
|
|
spacing = dpi(10),
|
|
layout = wibox.layout.fixed.horizontal
|
|
},
|
|
{ -- Spacing
|
|
forced_width = dpi(10),
|
|
widget = wibox.container.background
|
|
},
|
|
{
|
|
{
|
|
{
|
|
{
|
|
id = "con",
|
|
resize = false,
|
|
valign = "center",
|
|
halign = "center",
|
|
forced_width = dpi(24),
|
|
forced_height = dpi(24),
|
|
widget = wibox.widget.imagebox
|
|
},
|
|
id = "place",
|
|
strategy = "max",
|
|
width = dpi(24),
|
|
height = dpi(24),
|
|
widget = wibox.container.constraint
|
|
},
|
|
id = "margin",
|
|
margins = dpi(2),
|
|
widget = wibox.container.margin
|
|
},
|
|
id = "margin0",
|
|
margin = dpi(5),
|
|
widget = wibox.container.margin
|
|
},
|
|
id = "device_layout",
|
|
layout = wibox.layout.align.horizontal
|
|
},
|
|
id = "device_margin",
|
|
margins = dpi(5),
|
|
widget = wibox.container.margin
|
|
},
|
|
bg = Theme_config.network_manager.access_point.bg,
|
|
fg = Theme_config.network_manager.access_point.fg,
|
|
border_color = Theme_config.network_manager.access_point.border_color,
|
|
border_width = Theme_config.network_manager.access_point.border_width,
|
|
id = "background",
|
|
shape = Theme_config.network_manager.access_point.device_shape,
|
|
widget = wibox.container.background
|
|
})
|
|
|
|
gtable.crush(ret, access_point, true)
|
|
|
|
ret.NetworkManagerAccessPoint = args.NetworkManagerAccessPoint
|
|
ret.NetworkManagerSettings = args.NetworkManagerSettings
|
|
ret.NetworkManagerDeviceWireless = args.NetworkManagerDeviceWireless
|
|
ret.NetworkManagerDevice = args.NetworkManagerDevice
|
|
ret.NetworkManager = args.NetworkManager
|
|
|
|
ret.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new {
|
|
bus = dbus_proxy.Bus.SYSTEM,
|
|
name = "org.freedesktop.NetworkManager",
|
|
interface = "org.freedesktop.DBus.Properties",
|
|
path = ret.NetworkManagerAccessPoint.object_path,
|
|
}
|
|
|
|
-- Update the access point strength
|
|
ret.NetworkManagerAccessPointProperties:connect_signal(function(_, properties, data)
|
|
if data.Strength then
|
|
awesome.emit_signal("NM::AccessPointStrength", data.Strength)
|
|
if ret.is_ap_active(ret.NetworkManagerAccessPoint.object_path) then
|
|
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
|
icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg",
|
|
Theme_config.network_manager.access_point.icon_color2)
|
|
else
|
|
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
|
icondir .. "wifi-strength-" .. math.floor(data.Strength / 25) + 1 .. ".svg",
|
|
Theme_config.network_manager.access_point.icon_color)
|
|
end
|
|
end
|
|
end, "PropertiesChanged")
|
|
|
|
if ret:is_ap_active(ret.NetworkManagerAccessPoint) then
|
|
ret.bg = Theme_config.network_manager.access_point.fg
|
|
ret.fg = Theme_config.network_manager.access_point.bg
|
|
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
|
icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
|
Theme_config.network_manager.access_point.icon_color2)
|
|
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(
|
|
icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color2)
|
|
else
|
|
ret.bg = Theme_config.network_manager.access_point.bg
|
|
ret.fg = Theme_config.network_manager.access_point.fg
|
|
ret:get_children_by_id("icon")[1].image = gcolor.recolor_image(
|
|
icondir .. "wifi-strength-" .. math.floor(ret.NetworkManagerAccessPoint.Strength / 25) + 1 .. ".svg",
|
|
Theme_config.network_manager.access_point.icon_color)
|
|
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(
|
|
icondir .. "link.svg", Theme_config.network_manager.access_point.icon_color)
|
|
end
|
|
|
|
ret.ap_form = ap_form {
|
|
screen = args.screen,
|
|
NetworkManagerAccessPoint = args.NetworkManagerAccessPoint,
|
|
ap = ret
|
|
}
|
|
|
|
ret.cm = cm {
|
|
widget_template = wibox.widget {
|
|
{
|
|
{
|
|
{
|
|
{
|
|
widget = wibox.widget.imagebox,
|
|
resize = true,
|
|
valign = "center",
|
|
halign = "center",
|
|
id = "icon_role",
|
|
},
|
|
widget = wibox.container.constraint,
|
|
stragety = "exact",
|
|
width = dpi(24),
|
|
height = dpi(24),
|
|
id = "const"
|
|
},
|
|
{
|
|
widget = wibox.widget.textbox,
|
|
valign = "center",
|
|
halign = "left",
|
|
id = "text_role"
|
|
},
|
|
layout = wibox.layout.fixed.horizontal
|
|
},
|
|
widget = wibox.container.margin
|
|
},
|
|
widget = wibox.container.background,
|
|
}, spacing = dpi(10),
|
|
entries = {
|
|
{ -- Connect/Disconnect a device
|
|
name = "ret.device.Connected" and "Disconnect" or "Connect",
|
|
icon = gcolor.recolor_image("ret.device.Connected" and icondir .. "link-off.svg" or
|
|
icondir .. "link.svg",
|
|
Theme_config.network_manager.access_point.icon_color),
|
|
callback = function()
|
|
ret:toggle_connection(ret.NetworkManagerAccessPoint)
|
|
end,
|
|
id = "connected"
|
|
}
|
|
}
|
|
}
|
|
|
|
ret:buttons(gtable.join(
|
|
abutton({}, 1, nil,
|
|
function()
|
|
if ret:is_ap_active(ret.NetworkManagerAccessPoint) then
|
|
ret:disconnect()
|
|
else
|
|
ret.ap_form:popup_toggle()
|
|
end
|
|
end
|
|
),
|
|
abutton({}, 3, nil,
|
|
function()
|
|
ret.cm:toggle()
|
|
end
|
|
)
|
|
))
|
|
|
|
Hover_signal(ret)
|
|
|
|
return ret
|
|
end
|
|
|
|
function access_point.mt:__call(...)
|
|
return access_point.new(...)
|
|
end
|
|
|
|
return setmetatable(access_point, access_point.mt)
|