new network daemon(not finished)

This commit is contained in:
Rene Kievits
2023-05-13 21:58:38 +02:00
parent 3bae4f4403
commit 1c7d2be751
4 changed files with 356 additions and 53 deletions

View File

@@ -0,0 +1,79 @@
local gtable = require('gears.table')
local gobject = require('gears.object')
local NM = require('lgi').NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local instance = nil
if not instance then
instance = setmetatable({}, {
__call = function(_, device_path)
local self = gobject {}
self.object_path = device_path
self.NetworkManagerAccessPoint = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.AccessPoint',
path = device_path,
}
if not NM.utils_ssid_to_utf8(self.NetworkManagerAccessPoint.Ssid) then
self.NetworkManagerAccessPoint = nil
self = nil
return nil
end
self.NetworkManagerAccessPointProperties = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.DBus.Properties',
path = device_path,
}
self.NetworkManagerAccessPointProperties:connect_signal(function(_, _, data)
if data.Strength then
self:emit_signal('NetworkManagerAccessPoint::Strength', data.Strength)
elseif data.LastSeen then
self:emit_signal('NetworkManagerAccessPoint::LastSeen', data.LastSeen)
end
end, 'PropertiesChanged')
self:emit_signal('NetworkManagerAccessPoint::Strength', self.NetworkManagerAccessPoint.Strength)
setmetatable(self, {
__index = function(s, key)
if key == 'SSID' then
return NM.utils_ssid_to_utf8(s.NetworkManagerAccessPoint.Ssid)
elseif key == 'Frequency' then
return s.NetworkManagerAccessPoint.Frequency
elseif key == 'MaxBitrate' then
return s.NetworkManagerAccessPoint.MaxBitrate
elseif key == 'HwAddress' then
return s.NetworkManagerAccessPoint.HwAddress
elseif key == 'Strength' then
return s.NetworkManagerAccessPoint.Strength
elseif key == 'Security' then
local str = ''
if s.Flags == 1 and s.WpaFlags == 0 and s.RsnFlags == 0 then
str = str .. ' WEP'
end
if s.WpaFlags ~= 0 then
str = str .. ' WPA1'
end
if not s.RsnFlags ~= 0 then
str = str .. ' WPA2'
end
if s.WpaFlags == 512 or s.RsnFlags == 512 then
str = str .. ' 802.1X'
end
return (str:gsub('^%s', ''))
end
end,
})
return self
end,
})
end
return instance

View File

@@ -1,19 +1,19 @@
local lgi = require('lgi')
local NM = lgi.NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local gtable = require('gears.table')
local gobject = require('gears.object')
local device = gobject {}
local WIRELESS = gobject {}
local access_point = require('src.tools.network.access_point')
local device = {}
device._private = {}
local WIRELESS = {}
device.DeviceType = {
device._private.DeviceType = {
ETHERNET = 1,
WIFI = 2,
}
device.DeviceState = {
device._private.DeviceState = {
UNKNOWN = 0,
UNMANAGED = 10,
UNAVAILABLE = 20,
@@ -29,17 +29,32 @@ device.DeviceState = {
FAILED = 120,
}
function WIRELESS:IsApActive(ap)
return self.NetworkManagerDeviceWireless.ActiveAccessPoint == ap.object_path
end
function WIRELESS:GetAllAccessPoints()
return self.NetworkManagerDeviceWireless:GetAllAccessPoints()
end
function WIRELESS:RequestScan()
--TODO: Are options needed? What do they do?
self.NetworkManagerDeviceWireless:RequestScan {}
--- If we scan we simply update the list that holds all access points
--- We can then get the list and create a new access point for all devices
---@param callback any
function WIRELESS:RequestScan(callback)
local ap_list = {}
self.NetworkManagerDeviceWireless:RequestScanAsync(function(_, _, _, failure)
for _, value in ipairs(self.NetworkManagerDeviceWireless:GetAllAccessPoints()) do
table.insert(ap_list, access_point(value))
end
callback(ap_list)
end, { call_id = 'AMOGUS' }, {})
end
return setmetatable(device, {
__call = function(self, device_path)
__call = function(_, device_path)
local self = gobject {}
gtable.crush(self, device, true)
self.object_path = device_path
self.NetworkManagerDevice = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
@@ -51,9 +66,8 @@ return setmetatable(device, {
self:emit_signal('NetworkManagerDevice::StateChanged', new_state, reason)
end, 'StateChanged')
if self.NetworkManagerDevice.DeviceType == self.DeviceType.WIFI then
gtable.crush(self, WIRELESS)
if self.NetworkManagerDevice.DeviceType == self._private.DeviceType.WIFI then
gtable.crush(self, WIRELESS, true)
self.NetworkManagerDeviceWireless = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
@@ -73,19 +87,35 @@ return setmetatable(device, {
self:emit_signal('NetworkManagerDeviceWireless::Bitrate', data.Bitrate)
end
if data.ActiveAccessPoint then
self.emit_signal('NetworkManagerDeviceWireless::ActiveAccessPoint', data.ActiveAccessPoint)
self:emit_signal('NetworkManagerDeviceWireless::ActiveAccessPoint', self.current_ap, data.ActiveAccessPoint)
self.current_ap = data.ActiveAccessPoint
end
end, 'PropertiesChanged')
self.current_ap = self.NetworkManagerDeviceWireless.ActiveAccessPoint
self.ap_list = {}
self.NetworkManagerDeviceWireless:connect_signal(function(_, path)
self:emit_signal('NetworkManagerDeviceWireless::AccessPointAdded', path)
--check if path is already in list
for _, value in ipairs(self.ap_list) do
if value == path then
return
end
end
table.insert(self.ap_list, path)
self:emit_signal('NetworkManagerDeviceWireless::AccessPointAdded', access_point(path))
end, 'AccessPointAdded')
self.NetworkManagerDeviceWireless:connect_signal(function(_, path)
self:emit_signal('NetworkManagerDeviceWireless::AccessPointRemoved', path)
for i, value in ipairs(self.ap_list) do
if value == path then
table.remove(self.ap_list, i)
return
end
end
end, 'AccessPointRemoved')
elseif self.NetworkManagerDevice.DeviceType == self.DeviceType.ETHERNET then
elseif self.NetworkManagerDevice.DeviceType == self._private.DeviceType.ETHERNET then
self.NetworkManagerDeviceWired = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
@@ -108,25 +138,28 @@ return setmetatable(device, {
self:emit_signal('NetworkManagerDeviceWired::Carrier', data.Carrier)
end
end, 'PropertiesChanged')
end
setmetatable(self, {
__index = function(self, key)
if key == 'DeviceType' then
return self.NetworkManagerDevice.DeviceType
elseif key == 'State' then
return self.NetworkManagerDevice.State
elseif key == 'StateReason' then
return self.NetworkManagerDevice.StateReason
elseif key == 'Bitrate' then
if self.NetworkManagerDeviceWireless then
return self.NetworkManagerDeviceWireless.Bitrate
end
elseif key == 'Managed' then
return self.NetworkManagerDevice.Managed
elseif key == 'ActiveConnection' then
return self.NetworkManagerDevice.ActiveConnection
end
end,
})
return self
end,
__index = function(self, key)
if key == 'DeviceType' then
return self.NetworkManagerDevice.DeviceType
elseif key == 'State' then
return self.NetworkManagerDevice.State
elseif key == 'StateReason' then
return self.NetworkManagerDevice.StateReason
elseif key == 'Bitrate' then
if self.NetworkManagerDeviceWireless then
return self.NetworkManagerDeviceWireless.Bitrate
end
elseif key == 'Managed' then
return self.NetworkManagerDevice.Managed
elseif key == 'ActiveConnection' then
return self.NetworkManagerDevice.ActiveConnection
end
end,
})

View File

@@ -1,9 +1,11 @@
local lgi = require('lgi')
local gobject = require('gears.object')
local NM = require('lgi').NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local nmdevice = require('src.tools.network.device')
local settings = require('src.tools.network.settings')
local network = gobject {}
@@ -39,17 +41,63 @@ network.DeviceState = {
FAILED = 120,
}
function network:toggle_network()
self._private.NetworkManager:Set('org.freedesktop.NetworkManager', 'NetworkingEnabled', lgi.GLib.Variant('b', not self.NetworkingEnabled))
---Will try to connect to an access point by first searching if the connection already exists
--- and then adding the connection if its not.
---@param ap any
---@param connection any
---@param callback any
function network:ConnectToAccessPointAsync(ap, device, connection, callback)
print(ap, connection)
for path, value in pairs(self.NetworkManagerSettings.ConnectionList or {}) do
print(--[[ connection.connection.id.value, ]] ap.SSID, value:GetSettings().connection.id)
if (connection and connection.connection.id.value or ap.SSID) == value:GetSettings().connection.id then
if connection then
value:Update(connection)
end
self.NetworkManager:ActivateConnectionAsync(function(_, _, succ, failure)
print(failure, succ)
if failure then
callback(false)
return
else
callback(true)
return
end
end, { call_id = 'amogus' }, path, device.object_path, ap.object_path)
return
end
end
if not connection then
callback(false)
return
end
self.NetworkManager:AddAndActivateConnectionAsync(function(_, _, succ, fail)
if fail then
callback(false)
return
else
callback(true)
return
end
end, { call_id = 'amogus' }, connection, device.object_path, ap.object_path)
end
function network:get_active_device()
for path, device in pairs(self.Devices) do
print(device.ActiveConnection, path)
if device.State == self.DeviceState.ACTIVATED then
print(device, path)
else
print('no active device')
function network:DisconnectFromAP()
self.NetworkManager:DeactivateConnection(self:get_wireless_device().ActiveConnection)
end
--TODO: Make sure this works, I don't know how its going
--TODO: to work if there were multiple wireless devices, probably try
--TODO: to find the one that is active or something like that
function network:get_wireless_device()
for _, device in pairs(self.Devices) do
print(device.DeviceType, device.device_path)
if device.DeviceType == self.DeviceType.WIFI then
return device
end
end
end
@@ -60,16 +108,19 @@ function network:get_devices()
for _, device in ipairs(devices) do
self.Devices[device] = nmdevice(device)
self.Devices[device]:connect_signal('NetworkManagerDevice::StateChanged', function(_, s, r)
print(device, s, r)
end)
end
end
function network:toggle_network()
self.NetworkManager:Set('org.freedesktop.NetworkManager', 'NetworkingEnabled', lgi.GLib.Variant('b', not self.NetworkingEnabled))
end
function network:toggle_wifi()
if not self.NetworkingEnabled then
if self.NetworkingEnabled == false then
self:toggle_network()
end
self._private.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', not self.NetworkingEnabled))
self.NetworkManager:Set('org.freedesktop.NetworkManager', 'WirelessEnabled', lgi.GLib.Variant('b', not self.WirelessEnabled))
end
local instance = nil
@@ -90,12 +141,7 @@ if not instance then
path = '/org/freedesktop/NetworkManager',
}
self.NetworkManagerSettings = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings',
path = '/org/freedesktop/NetworkManager/Settings',
}
self.NetworkManagerSettings = settings()
self.NetworkManager:connect_signal(function(_, device_path)
if device_path then
@@ -120,8 +166,17 @@ if not instance then
end
end, 'PropertiesChanged')
-- Init values because signal isn't emitted on startup
self:emit_signal('NetworkManager::WirelessEnabled', self.NetworkManager.WirelessEnabled)
self:emit_signal('NetworkManager::NetworkingEnabled', self.NetworkManager.NetworkingEnabled)
self.WirelessEnabled = self.NetworkManager.WirelessEnabled
self.NetworkingEnabled = self.NetworkManager.NetworkingEnabled
self:get_devices()
self:get_active_device()
return self
end,
})
end

View File

@@ -0,0 +1,136 @@
local gobject = require('gears.object')
local gtable = require('gears.table')
local lgi = require('lgi')
local NM = require('lgi').NM
local dbus_proxy = require('src.lib.lua-dbus_proxy.src.dbus_proxy')
local settings = gobject {}
---Get a connection path by uuid
---@param uuid string
---@return string connection_path
function settings:GetConnectionByUUID(uuid)
return self.NetworkManagerSettings:GetConnectionByUuid(uuid) or ''
end
function settings:GetConnectionForSSID(ssid)
for _, con in pairs(self.ConnectionList) do
if con:GetSettings().connection.id == ssid then
return con
end
end
end
--! For some reason not working, using AddAndActivateConnection instead works and adds the connection just fine
---Tries to add a new connection to the connections and returns the path if successfull
---@param con table connection
---@return string?
function settings:AddConnection(con)
--[[ local c = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = '/org/freedesktop/NetworkManager/Settings/',
} ]]
--[[ c:Update(con)
print('No Problem')
print(c:GetSettings().connection.id) ]]
--local path = self.NetworkManagerSettings:AddConnection(con)
--print(path)
--return path
end
function settings:RemoveConnection(con)
if not con then return end
con:Delete()
end
---Returns a new and valid connection table
---@param args {passwd: string, security: string, autoconnect: boolean, ssid: string}
---@return table
function settings:NewConnectionProfile(args)
local security = {}
if args.security:match('WPA') then
security = {
['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk'),
['auth-alg'] = lgi.GLib.Variant('s', 'open'),
['psk'] = lgi.GLib.Variant('s', args.passwd),
}
else
security = {
['key-mgmt'] = lgi.GLib.Variant('s', 'wpa-psk'),
['wep-key-type'] = lgi.GLib.Variant('s', NM.WepKeyType.PASSPHRASE),
['wep-key0'] = lgi.GLib.Variant('s', args.passwd),
}
end
return {
['connection'] = {
['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', args.ssid),
['type'] = lgi.GLib.Variant('s', '802-11-wireless'),
['autoconnect'] = lgi.GLib.Variant('b', args.autoconnect),
},
['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'] = security,
}
end
local instance = nil
if not instance then
instance = setmetatable(settings, {
__call = function(self)
self.NetworkManagerSettings = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings',
path = '/org/freedesktop/NetworkManager/Settings',
}
self.ConnectionList = {}
for _, value in pairs(self.NetworkManagerSettings:ListConnections()) do
local c = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = value,
}
if c then self.ConnectionList[value] = c end
end
self.NetworkManagerSettings:connect_signal(function(_, con)
print('New!', con)
local c = dbus_proxy.Proxy:new {
bus = dbus_proxy.Bus.SYSTEM,
name = 'org.freedesktop.NetworkManager',
interface = 'org.freedesktop.NetworkManager.Settings.Connection',
path = con,
}
self.ConnectionList[con] = c
end, 'NewConnection')
self.NetworkManagerSettings:connect_signal(function(_, con)
print('Removed!', con)
self.ConnectionList[con] = nil
end, 'ConnectionRemoved')
return self
end,
})
end
return instance