class wifi+ { private import rt::c, lib::dbus; struct wifi { conn void; err DBusError; wicd wicd; wicd_wl wicd_wl; } func constructor() { this.conn = null; dbus_error_init(&this.err); } func destructor() { dbus_error_free(&this.err); } func init() bool { this.conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this.err); if dbus_error_is_set(&this.err); return false; this.wicd->init(this.conn); this.wicd_wl->init(this.conn); return true; } // func get_signal_strength() int { var iwconfig. char = null; if this.wicd->needs_external_calls() { if (iwconfig = this.wicd_wl->get_iwconfig()) == null; return -1; iwconfig = strdup(iwconfig); } if this.wicd->get_signal_disply_type() == 0 { func = this.wicd_wl->get_cur_signal_strength(iwconfig); else func = this.wicd_wl->get_cur_dbm_strength(iwconfig); } if iwconfig ~= null; free(iwconfig); } func is_connecting() bool { return this.wicd_wl->check_if_wireless_connecting(); } func is_connected(signal_strength. int = null) bool { if this.wicd_wl->check_if_wireless_connecting(); return false; var x int = this->get_signal_strength(); if x == -1; return false; if signal_strength ~= null; .signal_strength = x; return true; } func scan(sync bool = false) { this.wicd_wl->scan(sync); } func connect(id int) { this.wicd_wl->connect(id); } // inline get_sys_bus() void { return this.conn; } inline get_bus_err() .DBusError { return &this.err; } } class wifi+, signal_thread { private import rt::c, lib::dbus; private alias string = std::string, vector = std::vector; struct hook { iface. char; sig_name. char; callback void; arg void; } struct signal_thread { thread pthread_t; wifi. wifi; hooks vector; } func constructor() { this.thread = null; this.wifi = null; constructor(this); } func destructor() { this->stop(); destructor(this); } func init(wifi. wifi) { this.wifi = wifi; } /* callback = lambda(arg void, iter void) [ ... ]; */ func hook_signal(iface. char, sig_name. char, callback void, arg void) bool { if this.thread ~= null; return false; var conn void = this.wifi->get_sys_bus(); var err void = this.wifi->get_bus_err(); using rule string; dbus_bus_add_match(conn, rule->format("type='signal',interface='%s'", iface), err); dbus_connection_flush(conn); if dbus_error_is_set(err); return false; var hook. hook = this.hooks->new(); hook.iface = iface; hook.sig_name = sig_name; hook.callback = callback; hook.arg = arg; return true; } func start() bool { if this.thread ~= null; return true; if pthread_create(&this.thread, null, lambda(this.signal_thread) void [ var conn void = this.wifi->get_sys_bus(); while this.thread ~= null { for ;; { dbus_connection_read_write(conn, 0); var msg void = dbus_connection_pop_message(conn); if msg == null; break; forvar index size_t = 0, count size_t = this.hooks->count(); index < count; index++ { var hook. hook = this.hooks->at(index); if dbus_message_is_signal(msg, hook.iface, hook.sig_name) { var iter void; if !dbus_message_iter_init(msg, &iter); iter = null; proto fn(arg void, iter void); fn[hook.callback](hook.arg, iter); break; } } dbus_message_unref(msg); } sleep(1); } ], this)); return false; return true; } func stop() { var thread pthread_t = this.thread; if thread ~= null { this.thread = null; pthread_join(thread, null); } } } class wifi+, dbus { private import lib::dbus; struct dbus { conn void; bus_name. char; path. char; iface. char; } func init(conn void, bus_name. char, path. char, iface. char) { this.conn = conn; this.bus_name = bus_name; this.path = path; this.iface = iface; } func call(method. char, format. char = null, ...) void { var msg void = dbus_message_new_method_call(this.bus_name, this.path, this.iface, method); if msg == null; return null; defer dbus_message_unref(msg); if format ~= null { var args DBusMessageIter; dbus_message_iter_init_append(msg, &args); forvar ap void = va_start(this) ;; { var type char = .format++; if !type; break; if !dbus_message_iter_append_basic(&args, type, ap); return null; va_next(ap); } } if !dbus_connection_send_with_reply(this.conn, msg, &func, -1); return null; if func ~= null; dbus_connection_flush(this.conn); } static func get(pending void, format. char = null, ...) bool { if pending == null; return false; dbus_pending_call_block(pending); var msg void = dbus_pending_call_steal_reply(pending); dbus_pending_call_unref(pending); if msg == null; return false; defer dbus_message_unref(msg); if format ~= null { var args DBusMessageIter; if dbus_message_iter_init(msg, &args) { forvar ap. void = va_start(pending) ;; { var type char = .format++; if !type; break; if dbus_message_iter_get_arg_type(&args) ~= type; return false; dbus_message_iter_get_basic(&args, .ap); if !dbus_message_iter_next(&args); break; va_next(ap); } } } return true; } } class wifi+, wicd { private import lib::dbus; struct wicd { bus dbus; } func init(conn void) { this.bus->init(conn, "org.wicd.daemon", "/org/wicd/daemon", "org.wicd.daemon"); } func format_signal_for_printing(signal int) .char { func = null; this.bus->get( this.bus->call("FormatSignalForPrinting", "i", signal), "s", &func); } func get_signal_disply_type() int { func = -1; this.bus->get( this.bus->call("GetSignalDisplayType"), "i", &func); } func needs_external_calls() dbus_bool_t { func = 0; this.bus->get( this.bus->call("NeedsExternalCalls"), "b", &func); } } class wifi+, wicd_wl { private import lib::dbus; struct wicd_wl { bus dbus; } func init(conn void) { this.bus->init(conn, "org.wicd.daemon", "/org/wicd/daemon/wireless", "org.wicd.daemon.wireless"); } func check_if_wireless_connecting() dbus_bool_t { func = 0; this.bus->get( this.bus->call("CheckIfWirelessConnecting"), "b", &func); } func check_wireless_connecting_msg() .char { func = null; this.bus->get( this.bus->call("CheckWirelessConnectingMessage"), "s", &func); } // result? func connect(id int) { this.bus->get( this.bus->call("ConnectWireless", "i", id)); } func get_cur_dbm_strength(iwconfig. char) int { func = -1; var pending void; if iwconfig == null { pending = this.bus->call("GetCurrentDBMStrength"); else pending = this.bus->call("GetCurrentDBMStrength", "s", iwconfig); } this.bus->get(pending, "i", &func); } func get_cur_signal_strength(iwconfig. char) int { func = -1; var pending void; if iwconfig == null { pending = this.bus->call("GetCurrentSignalStrength"); else pending = this.bus->call("GetCurrentSignalStrength", "s", iwconfig); } this.bus->get(pending, "i", &func); } func get_cur_network(iwconfig. char) .char { func = null; var pending void; if iwconfig == null { pending = this.bus->call("GetCurrentNetwork"); else pending = this.bus->call("GetCurrentNetwork", "s", iwconfig); } this.bus->get(pending, "s", &func); } func get_cur_network_id(iwconfig. char) int { func = -1; var pending void; if iwconfig == null { pending = this.bus->call("GetCurrentNetworkID"); else pending = this.bus->call("GetCurrentNetworkID", "s", iwconfig); } this.bus->get(pending, "i", &func); } func get_iwconfig() .char { func = null; this.bus->get( this.bus->call("GetIwconfig"), "s", &func); } func get_num_of_networks() int { func = -1; this.bus->get( this.bus->call("GetNumberOfNetworks"), "i", &func); } func get_wireless_ip(s. char) .char { func = null; var pending void; if s == null { pending = this.bus->call("GetWirelessIP"); else pending = this.bus->call("GetWirelessIP", "s", s); } this.bus->get(pending, "s", &func); } func get_wireless_prop(id int, prop_name. char) .char { func = null; this.bus->get( this.bus->call("GetWirelessProperty", "is", id, prop_name), "s", &func); } // result? func scan(sync dbus_bool_t) { this.bus->get( this.bus->call("Scan", "b", sync)); } func set_wireless_prop_str(id int, prop_name. char, s. char) bool { return this.bus->get( this.bus->call("SetWirelessProperty", "iss", id, prop_name, s)); } func set_wireless_prop_int(id int, prop_name. char, i int) bool { return this.bus->get( this.bus->call("SetWirelessProperty", "isi", id, prop_name, i)); } }