mirror of
https://github.com/zoriya/astal.git
synced 2026-05-29 17:02:00 +00:00
monorepo structuring
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
public class AstalNetwork.AccessPoint : Object {
|
||||
private Wifi wifi;
|
||||
private NM.AccessPoint ap;
|
||||
|
||||
public uint bandwidth { get { return ap.bandwidth; } }
|
||||
public string bssid { owned get { return ap.bssid; } }
|
||||
public uint frequency { get { return ap.frequency; } }
|
||||
public int last_seen { get { return ap.last_seen; } }
|
||||
public uint max_bitrate { get { return ap.max_bitrate; } }
|
||||
public uint8 strength { get { return ap.strength; } }
|
||||
public string icon_name { get; private set; }
|
||||
public NM.80211Mode mode { get { return ap.mode; } }
|
||||
public NM.80211ApFlags flags { get { return ap.flags; } }
|
||||
public NM.80211ApSecurityFlags rsn_flags { get { return ap.rsn_flags; } }
|
||||
public NM.80211ApSecurityFlags wpa_flags { get { return ap.wpa_flags; } }
|
||||
|
||||
public string? ssid {
|
||||
owned get {
|
||||
if (ap.ssid == null)
|
||||
return null;
|
||||
|
||||
return (string)NM.Utils.ssid_to_utf8(ap.ssid.get_data());
|
||||
}
|
||||
}
|
||||
|
||||
internal AccessPoint(Wifi wifi, NM.AccessPoint ap) {
|
||||
this.wifi = wifi;
|
||||
this.ap = ap;
|
||||
ap.notify.connect((pspec) => {
|
||||
if (get_class().find_property(pspec.name) != null)
|
||||
notify_property(pspec.name);
|
||||
if (pspec.name == "strength")
|
||||
icon_name = _icon();
|
||||
});
|
||||
icon_name = _icon();
|
||||
}
|
||||
|
||||
private string _icon() {
|
||||
if (strength >= 80) return Wifi.ICON_EXCELLENT;
|
||||
if (strength >= 60) return Wifi.ICON_GOOD;
|
||||
if (strength >= 40) return Wifi.ICON_OK;
|
||||
if (strength >= 20) return Wifi.ICON_WEAK;
|
||||
return Wifi.ICON_NONE;
|
||||
}
|
||||
|
||||
// TODO: connect to ap
|
||||
// public signal void auth();
|
||||
// public void try_connect(string? password) { }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace AstalNetwork {
|
||||
public const int MAJOR_VERSION = @MAJOR_VERSION@;
|
||||
public const int MINOR_VERSION = @MINOR_VERSION@;
|
||||
public const int MICRO_VERSION = @MICRO_VERSION@;
|
||||
public const string VERSION = "@VERSION@";
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
project(
|
||||
'astal-network',
|
||||
'vala',
|
||||
'c',
|
||||
version: run_command('cat', join_paths(meson.project_source_root(), 'version')).stdout().strip(),
|
||||
meson_version: '>= 0.62.0',
|
||||
default_options: [
|
||||
'warning_level=2',
|
||||
'werror=false',
|
||||
'c_std=gnu11',
|
||||
],
|
||||
)
|
||||
|
||||
version_split = meson.project_version().split('.')
|
||||
api_version = version_split[0] + '.' + version_split[1]
|
||||
gir = 'AstalNetwork-' + api_version + '.gir'
|
||||
typelib = 'AstalNetwork-' + api_version + '.typelib'
|
||||
|
||||
config = configure_file(
|
||||
input: 'config.vala.in',
|
||||
output: 'config.vala',
|
||||
configuration: {
|
||||
'VERSION': meson.project_version(),
|
||||
'MAJOR_VERSION': version_split[0],
|
||||
'MINOR_VERSION': version_split[1],
|
||||
'MICRO_VERSION': version_split[2],
|
||||
},
|
||||
)
|
||||
|
||||
deps = [
|
||||
dependency('glib-2.0'),
|
||||
dependency('gobject-2.0'),
|
||||
dependency('libnm'),
|
||||
]
|
||||
|
||||
sources = [
|
||||
config,
|
||||
'network.vala',
|
||||
'wifi.vala',
|
||||
'wired.vala',
|
||||
'wired.vala',
|
||||
'accesspoint.vala',
|
||||
]
|
||||
|
||||
lib = library(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies: deps,
|
||||
vala_header: meson.project_name() + '.h',
|
||||
vala_vapi: meson.project_name() + '-' + api_version + '.vapi',
|
||||
vala_gir: gir,
|
||||
version: meson.project_version(),
|
||||
install: true,
|
||||
install_dir: [true, true, true, true],
|
||||
)
|
||||
|
||||
import('pkgconfig').generate(
|
||||
lib,
|
||||
name: meson.project_name(),
|
||||
filebase: meson.project_name() + '-' + api_version,
|
||||
version: meson.project_version(),
|
||||
subdirs: meson.project_name(),
|
||||
requires: deps,
|
||||
install_dir: get_option('libdir') / 'pkgconfig',
|
||||
)
|
||||
|
||||
custom_target(
|
||||
typelib,
|
||||
command: [
|
||||
find_program('g-ir-compiler'),
|
||||
'--output', '@OUTPUT@',
|
||||
'--shared-library', get_option('prefix') / get_option('libdir') / '@PLAINNAME@',
|
||||
meson.current_build_dir() / gir,
|
||||
],
|
||||
input: lib,
|
||||
output: typelib,
|
||||
depends: lib,
|
||||
install: true,
|
||||
install_dir: get_option('libdir') / 'girepository-1.0',
|
||||
)
|
||||
@@ -0,0 +1,206 @@
|
||||
namespace AstalNetwork {
|
||||
public Network get_default() {
|
||||
return Network.get_default();
|
||||
}
|
||||
}
|
||||
|
||||
public class AstalNetwork.Network : Object {
|
||||
private static Network instance;
|
||||
public static Network get_default() {
|
||||
if (instance == null)
|
||||
instance = new Network();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public NM.Client client { get; private set; }
|
||||
|
||||
public Wifi? wifi { get; private set; }
|
||||
public Wired? wired { get; private set; }
|
||||
public Primary primary { get; private set; }
|
||||
|
||||
public Connectivity connectivity {
|
||||
get { return (Connectivity)client.connectivity; }
|
||||
}
|
||||
|
||||
public State state {
|
||||
get { return (State)client.state; }
|
||||
}
|
||||
|
||||
construct {
|
||||
try {
|
||||
client = new NM.Client();
|
||||
var wifi_device = (NM.DeviceWifi)get_device(NM.DeviceType.WIFI);
|
||||
if (wifi_device != null)
|
||||
wifi = new Wifi(wifi_device);
|
||||
|
||||
var ethernet = (NM.DeviceEthernet)get_device(NM.DeviceType.ETHERNET);
|
||||
if (ethernet != null)
|
||||
wired = new Wired(ethernet);
|
||||
|
||||
sync();
|
||||
client.notify["primary-connection"].connect(sync);
|
||||
client.notify["activating-connection"].connect(sync);
|
||||
|
||||
client.notify["state"].connect(() => notify_property("state"));
|
||||
client.notify["connectivity"].connect(() => notify_property("connectivity"));
|
||||
} catch (Error err) {
|
||||
critical(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
private NM.Device get_device(NM.DeviceType t) {
|
||||
var valid = new GenericArray<NM.Device>();
|
||||
foreach (var device in client.get_devices()) {
|
||||
if (device.device_type == t)
|
||||
valid.add(device);
|
||||
}
|
||||
|
||||
foreach (var device in valid) {
|
||||
if (device.active_connection != null)
|
||||
return device;
|
||||
}
|
||||
|
||||
return valid.get(0);
|
||||
}
|
||||
|
||||
private void sync() {
|
||||
var ac = client.get_primary_connection();
|
||||
|
||||
if (ac == null)
|
||||
ac = client.get_activating_connection();
|
||||
|
||||
if (ac != null)
|
||||
primary = Primary.from_connection_type(ac.type);
|
||||
else
|
||||
primary = Primary.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public enum AstalNetwork.Primary {
|
||||
UNKNOWN,
|
||||
WIRED,
|
||||
WIFI;
|
||||
|
||||
public string to_string() {
|
||||
switch (this) {
|
||||
case WIFI: return "wifi";
|
||||
case WIRED: return "wired";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public static Primary from_connection_type(string type) {
|
||||
switch (type) {
|
||||
case "802-11-wireless": return Primary.WIFI;
|
||||
case "802-3-ethernet": return Primary.WIRED;
|
||||
default: return Primary.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// alias for NM.State
|
||||
public enum AstalNetwork.State {
|
||||
UNKNOWN,
|
||||
ASLEEP,
|
||||
DISCONNECTED,
|
||||
DISCONNECTING,
|
||||
CONNECTING,
|
||||
CONNECTED_LOCAL,
|
||||
CONNECTED_SITE,
|
||||
CONNECTED_GLOBAL;
|
||||
|
||||
public string to_string() {
|
||||
switch (this) {
|
||||
case ASLEEP: return "asleep";
|
||||
case DISCONNECTED: return "disconnected";
|
||||
case DISCONNECTING: return "disconnecting";
|
||||
case CONNECTING: return "connecting";
|
||||
case CONNECTED_LOCAL: return "connected_local";
|
||||
case CONNECTED_SITE: return "connected_site";
|
||||
case CONNECTED_GLOBAL: return "connected_global";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// alias for NM.ConnectivityState
|
||||
public enum AstalNetwork.Connectivity {
|
||||
UNKNOWN,
|
||||
NONE,
|
||||
PORTAL,
|
||||
LIMITED,
|
||||
FULL;
|
||||
|
||||
public string to_string() {
|
||||
switch (this) {
|
||||
case NONE: return "none";
|
||||
case PORTAL: return "portal";
|
||||
case LIMITED: return "limited";
|
||||
case FULL: return "full";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// alias for NM.DeviceState
|
||||
public enum AstalNetwork.DeviceState {
|
||||
UNKNOWN,
|
||||
UNMANAGED,
|
||||
UNAVAILABLE,
|
||||
DISCONNECTED,
|
||||
PREPARE,
|
||||
CONFIG,
|
||||
NEED_AUTH,
|
||||
IP_CONFIG,
|
||||
IP_CHECK,
|
||||
SECONDARIES,
|
||||
ACTIVATED,
|
||||
DEACTIVATING,
|
||||
FAILED;
|
||||
|
||||
public string to_string() {
|
||||
switch (this) {
|
||||
case UNMANAGED: return "unmanaged";
|
||||
case UNAVAILABLE: return "unavailable";
|
||||
case DISCONNECTED: return "disconnected";
|
||||
case PREPARE: return "prepare";
|
||||
case CONFIG: return "config";
|
||||
case NEED_AUTH: return "need_auth";
|
||||
case IP_CONFIG: return "ip_config";
|
||||
case IP_CHECK: return "ip_check";
|
||||
case SECONDARIES: return "secondaries";
|
||||
case ACTIVATED: return "activated";
|
||||
case DEACTIVATING: return "deactivating";
|
||||
case FAILED: return "failed";
|
||||
default: return "unknown";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public enum AstalNetwork.Internet {
|
||||
CONNECTED,
|
||||
CONNECTING,
|
||||
DISCONNECTED;
|
||||
|
||||
public static Internet from_device(NM.Device device) {
|
||||
if (device == null || device.active_connection == null)
|
||||
return DISCONNECTED;
|
||||
|
||||
switch (device.active_connection.state) {
|
||||
case NM.ActiveConnectionState.ACTIVATED: return CONNECTED;
|
||||
case NM.ActiveConnectionState.ACTIVATING: return CONNECTING;
|
||||
default: return DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
public string to_string() {
|
||||
switch (this) {
|
||||
case CONNECTED: return "connected";
|
||||
case CONNECTING: return "connecting";
|
||||
default: return "disconnected";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0.1.0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
public class AstalNetwork.Wifi : Object {
|
||||
internal const string ICON_EXCELLENT = "network-wireless-signal-excellent-symbolic";
|
||||
internal const string ICON_OK = "network-wireless-signal-ok-symbolic";
|
||||
internal const string ICON_GOOD = "network-wireless-signal-good-symbolic";
|
||||
internal const string ICON_WEAK = "network-wireless-signal-weak-symbolic";
|
||||
internal const string ICON_NONE = "network-wireless-signal-none-symbolic";
|
||||
internal const string ICON_ACQUIRING = "network-wireless-acquiring-symbolic";
|
||||
internal const string ICON_CONNECTED = "network-wireless-connected-symbolic";
|
||||
internal const string ICON_DISABLED = "network-wireless-disabled-symbolic";
|
||||
internal const string ICON_OFFLINE = "network-wireless-offline-symbolic";
|
||||
internal const string ICON_NO_ROUTE = "network-wireless-no-route-symbolic";
|
||||
internal const string ICON_HOTSPOT = "network-wireless-hotspot-symbolic";
|
||||
|
||||
private HashTable<string, AccessPoint> _access_points =
|
||||
new HashTable<string, AccessPoint>(str_hash, str_equal);
|
||||
|
||||
public NM.DeviceWifi device { get; construct set; }
|
||||
|
||||
public NM.ActiveConnection? active_connection { get; private set; }
|
||||
private ulong connection_handler = 0;
|
||||
|
||||
public AccessPoint? active_access_point { get; private set; }
|
||||
private ulong ap_handler = 0;
|
||||
|
||||
public List<weak AccessPoint> access_points {
|
||||
owned get { return _access_points.get_values(); }
|
||||
}
|
||||
|
||||
public bool enabled {
|
||||
get { return device.client.wireless_enabled; }
|
||||
set { device.client.wireless_enabled = value; }
|
||||
}
|
||||
|
||||
public Internet internet { get; private set; }
|
||||
public uint bandwidth { get; private set; }
|
||||
public string ssid { get; private set; }
|
||||
public uint8 strength { get; private set; }
|
||||
public uint frequency { get; private set; }
|
||||
public DeviceState state { get; private set; }
|
||||
public string icon_name { get; private set; }
|
||||
public bool is_hotspot { get; private set; }
|
||||
public bool scanning { get; private set; }
|
||||
|
||||
internal Wifi(NM.DeviceWifi device) {
|
||||
this.device = device;
|
||||
|
||||
foreach (var ap in device.access_points)
|
||||
_access_points.set(ap.bssid, new AccessPoint(this, ap));
|
||||
|
||||
device.access_point_added.connect((access_point) => {
|
||||
var ap = (NM.AccessPoint)access_point;
|
||||
_access_points.set(ap.bssid, new AccessPoint(this, ap));
|
||||
notify_property("access-points");
|
||||
});
|
||||
|
||||
device.access_point_removed.connect((access_point) => {
|
||||
var ap = (NM.AccessPoint)access_point;
|
||||
_access_points.remove(ap.bssid);
|
||||
notify_property("access-points");
|
||||
});
|
||||
|
||||
on_active_connection();
|
||||
device.notify["active-connection"].connect(on_active_connection);
|
||||
|
||||
on_active_access_point();
|
||||
device.notify["active-access-point"].connect(on_active_access_point);
|
||||
|
||||
state = (DeviceState)device.state;
|
||||
device.client.notify["wireless-enabled"].connect(() => notify_property("enabled"));
|
||||
device.state_changed.connect((n, o, r) => {
|
||||
state_changed(n, o, r);
|
||||
state = (DeviceState)n;
|
||||
});
|
||||
|
||||
device.notify.connect(() => { icon_name = _icon(); });
|
||||
device.client.notify.connect(() => { icon_name = _icon(); });
|
||||
icon_name = _icon();
|
||||
}
|
||||
|
||||
public signal void state_changed(
|
||||
DeviceState new_state,
|
||||
DeviceState old_state,
|
||||
NM.DeviceStateReason reaseon
|
||||
);
|
||||
|
||||
public void scan() {
|
||||
scanning = true;
|
||||
var last_scan = device.last_scan;
|
||||
device.request_scan_async.begin(null, (_, res) => {
|
||||
try {
|
||||
device.request_scan_async.end(res);
|
||||
Timeout.add(1000, () => {
|
||||
if (device.last_scan == last_scan)
|
||||
return Source.CONTINUE;
|
||||
|
||||
scanning = false;
|
||||
return Source.REMOVE;
|
||||
}, Priority.DEFAULT);
|
||||
} catch (Error err) {
|
||||
critical(err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void on_active_connection() {
|
||||
if (connection_handler > 0 && active_connection != null) {
|
||||
active_connection.disconnect(connection_handler);
|
||||
connection_handler = 0;
|
||||
active_connection = null;
|
||||
}
|
||||
|
||||
active_connection = device.active_connection;
|
||||
is_hotspot = _hotspot();
|
||||
if (active_connection != null) {
|
||||
connection_handler = active_connection.notify["state"].connect(() => {
|
||||
internet = Internet.from_device(device);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void on_active_access_point_notify() {
|
||||
bandwidth = active_access_point.bandwidth;
|
||||
frequency = active_access_point.frequency;
|
||||
strength = active_access_point.strength;
|
||||
ssid = active_access_point.ssid;
|
||||
}
|
||||
|
||||
private void on_active_access_point() {
|
||||
if (ap_handler > 0 && active_access_point != null) {
|
||||
active_access_point.disconnect(ap_handler);
|
||||
ap_handler = 0;
|
||||
active_access_point = null;
|
||||
}
|
||||
|
||||
var ap = device.active_access_point;
|
||||
if (ap != null) {
|
||||
active_access_point = _access_points.get(ap.bssid);
|
||||
on_active_access_point_notify();
|
||||
ap_handler = active_access_point.notify.connect(on_active_access_point_notify);
|
||||
}
|
||||
}
|
||||
|
||||
private string _icon() {
|
||||
if (!enabled) return ICON_DISABLED;
|
||||
|
||||
var full = device.client.connectivity == NM.ConnectivityState.FULL;
|
||||
|
||||
if (internet == Internet.CONNECTED) {
|
||||
if (is_hotspot) return ICON_HOTSPOT;
|
||||
if (!full) return ICON_NO_ROUTE;
|
||||
if (active_access_point == null) return ICON_CONNECTED;
|
||||
|
||||
if (strength >= 80) return ICON_EXCELLENT;
|
||||
if (strength >= 60) return ICON_GOOD;
|
||||
if (strength >= 40) return ICON_OK;
|
||||
if (strength >= 20) return ICON_WEAK;
|
||||
|
||||
return ICON_NONE;
|
||||
}
|
||||
|
||||
if (internet == Internet.CONNECTING) {
|
||||
return ICON_ACQUIRING;
|
||||
}
|
||||
|
||||
return ICON_OFFLINE;
|
||||
}
|
||||
|
||||
private bool _hotspot() {
|
||||
if (device.active_connection == null)
|
||||
return false;
|
||||
|
||||
var conn = device.active_connection.connection;
|
||||
if (conn == null)
|
||||
return false;
|
||||
|
||||
var ip4config = conn.get_setting_ip4_config();
|
||||
if (ip4config == null)
|
||||
return false;
|
||||
|
||||
return ip4config.method == NM.SettingIP4Config.METHOD_SHARED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
public class AstalNetwork.Wired : Object {
|
||||
private const string ICON_CONNECTED = "network-wired-symbolic";
|
||||
private const string ICON_DISCONNECTED = "network-wired-disconnected-symbolic";
|
||||
private const string ICON_ACQUIRING = "network-wired-acquiring-symbolic";
|
||||
private const string ICON_NO_ROUTE = "network-wired-no-route-symbolic";
|
||||
|
||||
public NM.DeviceEthernet device { get; construct set; }
|
||||
|
||||
public NM.ActiveConnection connection;
|
||||
private ulong connection_handler = 0;
|
||||
|
||||
internal Wired(NM.DeviceEthernet device) {
|
||||
this.device = device;
|
||||
|
||||
speed = device.speed;
|
||||
state = (DeviceState)device.state;
|
||||
icon_name = _icon();
|
||||
|
||||
device.notify.connect((pspec) => {
|
||||
if (pspec.name == "speed") {
|
||||
speed = device.speed;
|
||||
}
|
||||
if (pspec.name == "state") {
|
||||
state = (DeviceState)device.state;
|
||||
}
|
||||
if (pspec.name == "active-connection") {
|
||||
on_active_connection();
|
||||
}
|
||||
icon_name = _icon();
|
||||
});
|
||||
|
||||
device.client.notify.connect(() => { icon_name = _icon(); });
|
||||
|
||||
on_active_connection();
|
||||
icon_name = _icon();
|
||||
}
|
||||
|
||||
private void on_active_connection() {
|
||||
if (connection_handler > 0 && connection != null) {
|
||||
connection.disconnect(connection_handler);
|
||||
connection_handler = 0;
|
||||
connection = null;
|
||||
}
|
||||
|
||||
connection = device.active_connection;
|
||||
if (connection != null) {
|
||||
connection_handler = connection.notify["state"].connect(() => {
|
||||
internet = Internet.from_device(device);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public uint speed { get; private set; }
|
||||
public Internet internet { get; private set; }
|
||||
public DeviceState state { get; private set; }
|
||||
public string icon_name { get; private set; }
|
||||
|
||||
private string _icon() {
|
||||
var full = device.client.connectivity == NM.ConnectivityState.FULL;
|
||||
|
||||
if (internet == Internet.CONNECTING) {
|
||||
return ICON_ACQUIRING;
|
||||
}
|
||||
|
||||
if (internet == Internet.CONNECTED) {
|
||||
if (!full) return ICON_NO_ROUTE;
|
||||
|
||||
return ICON_CONNECTED;
|
||||
}
|
||||
|
||||
return ICON_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user