Compare commits

...

Author SHA1 Message Date
  Maciek Borzecki e8a2bd4001 application: monitor network changes, announce oneself when network becomes available 7 years ago
  Maciek Borzecki 504e3a7ce9 core, discovery, packet: WIP 7 years ago
  Maciek Borzecki d2f421e52b discovery, discovery-proxy: support self annoucement 7 years ago
7 changed files with 162 additions and 60 deletions
Split View
  1. +1
    -0
      meson.build
  2. +17
    -0
      src/mconnect/application.vala
  3. +18
    -3
      src/mconnect/core.vala
  4. +2
    -4
      src/mconnect/device.vala
  5. +45
    -0
      src/mconnect/discovery-proxy.vala
  6. +75
    -52
      src/mconnect/discovery.vala
  7. +4
    -1
      src/mconnect/packet.vala

+ 1
- 0
meson.build View File

@ -23,6 +23,7 @@ add_project_arguments(['--vapidir',
mconnect_src = [
'src/mconnect/main.vala',
'src/mconnect/discovery.vala',
'src/mconnect/discovery-proxy.vala',
'src/mconnect/packet.vala',
'src/mconnect/device.vala',
'src/mconnect/discovereddevice.vala',


+ 17
- 0
src/mconnect/application.vala View File

@ -36,8 +36,10 @@ namespace Mconn {
};
private Discovery discovery = null;
private DiscoveryDBusProxy bus_discovery = null;
private DeviceManager manager = null;
private DeviceManagerDBusProxy bus_manager = null;
private NetworkMonitor net_monitor = null;
public Application() {
Object(application_id: "org.mconnect");
@ -45,6 +47,7 @@ namespace Mconn {
discovery = new Discovery();
manager = new DeviceManager();
net_monitor = NetworkMonitor.get_default();
}
protected override void startup() {
@ -82,6 +85,8 @@ namespace Mconn {
debug("activate");
// reload devices from cache
manager.load_cache();
net_monitor.network_changed.connect(this.network_changed);
hold();
}
@ -91,6 +96,11 @@ namespace Mconn {
this.bus_manager = new DeviceManagerDBusProxy.with_manager(conn,
this.manager);
this.bus_manager.publish();
this.bus_discovery = new DiscoveryDBusProxy.with_discovery(conn,
this.discovery);
this.bus_discovery.publish();
base.dbus_register(conn, object_path);
debug("dbus register, path %s", object_path);
@ -103,5 +113,12 @@ namespace Mconn {
base.dbus_unregister(conn, object_path);
debug("dbus unregister, path %s", object_path);
}
private void network_changed(Object? monitor, bool available) {
debug("network connectivity changed: %s", available.to_string());
if (available == true) {
this.bus_discovery.announce();
}
}
}
}

+ 18
- 3
src/mconnect/core.vala View File

@ -29,6 +29,23 @@ class Core : Object {
public Config config { get; private set; default = null; }
public static string device_id {
owned get {
return Environment.get_host_name();
}
private set {}
}
public static string device_name {
owned get {
string host_name = Environment.get_host_name();
string user = Environment.get_user_name();
return @"$user@$host_name";
}
private set {}
}
private static Core _instance = null;
private Core() {
@ -84,11 +101,9 @@ class Core : Object {
"certificate.pem"));
if (key_file.query_exists() == false || cert_file.query_exists() == false) {
try {
string host_name = Environment.get_host_name();
string user = Environment.get_user_name();
Crypt.generate_key_cert(key_file.get_path(),
cert_file.get_path(),
@"$user@$host_name");
Core.device_name);
} catch (Error e) {
warning("failed to generate private key or certificate: %s", e.message);
throw e;


+ 2
- 4
src/mconnect/device.vala View File

@ -223,10 +223,8 @@ class Device : Object {
private async void greet() {
var core = Core.instance();
string host_name = Environment.get_host_name();
string user = Environment.get_user_name();
yield _channel.send(Packet.new_identity(@"$user@$host_name",
Environment.get_host_name(),
yield _channel.send(Packet.new_identity(core.device_name,
core.device_id,
core.handlers.interfaces,
core.handlers.interfaces));


+ 45
- 0
src/mconnect/discovery-proxy.vala View File

@ -0,0 +1,45 @@
/* ex:ts=4:sw=4:sts=4:et */
/* -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* AUTHORS
* Maciek Borzecki <maciek.borzecki (at] gmail.com>
*/
[DBus (name = "org.mconnect.Discovery")]
class DiscoveryDBusProxy : Object {
private Discovery discovery;
private const string DBUS_PATH = "/org/mconnect/discovery";
private DBusConnection bus = null;
public DiscoveryDBusProxy.with_discovery(DBusConnection bus,
Discovery discovery) {
this.discovery = discovery;
this.bus = bus;
}
[DBus (visible = false)]
public void publish() throws IOError {
assert(this.bus != null);
this.bus.register_object(DBUS_PATH, this);
}
public void announce() {
discovery.announce();
}
}

+ 75
- 52
src/mconnect/discovery.vala View File

@ -35,66 +35,89 @@ class Discovery : GLib.Object
}
public void listen() throws Error {
this.socket = new Socket(SocketFamily.IPV4,
SocketType.DATAGRAM,
SocketProtocol.UDP);
var sa = new InetSocketAddress(new InetAddress.any(SocketFamily.IPV4),
1714);
debug("start listening for new devices at: %s:%u",
sa.address.to_string(), sa.port);
try {
socket.bind(sa, false);
} catch (Error e) {
this.socket.close();
this.socket = null;
throw e;
}
var source = socket.create_source(IOCondition.IN);
source.set_callback((s, c) => {
this.incomingPacket();
return true;
});
source.attach(MainContext.default());
this.socket = new Socket(SocketFamily.IPV4,
SocketType.DATAGRAM,
SocketProtocol.UDP);
var sa = new InetSocketAddress(new InetAddress.any(SocketFamily.IPV4),
1714);
debug("start listening for new devices at: %s:%u",
sa.address.to_string(), sa.port);
try {
socket.bind(sa, false);
} catch (Error e) {
this.socket.close();
this.socket = null;
throw e;
}
var source = socket.create_source(IOCondition.IN);
source.set_callback((s, c) => {
this.incomingPacket();
return true;
});
source.attach(MainContext.default());
}
private void incomingPacket() {
vdebug("incoming packet");
vdebug("incoming packet");
uint8 buffer[4096];
SocketAddress sa;
InetSocketAddress isa;
uint8 buffer[4096];
SocketAddress sa;
InetSocketAddress isa;
try {
ssize_t read = this.socket.receive_from(out sa, buffer);
isa = (InetSocketAddress)sa;
vdebug("got %zd bytes from: %s:%u", read,
isa.address.to_string(), isa.port);
} catch (Error e) {
warning("failed to receive packet: %s", e.message);
return;
}
try {
ssize_t read = this.socket.receive_from(out sa, buffer);
isa = (InetSocketAddress)sa;
vdebug("got %zd bytes from: %s:%u", read,
isa.address.to_string(), isa.port);
} catch (Error e) {
warning("failed to receive packet: %s", e.message);
return;
}
vdebug("message data: %s", (string)buffer);
vdebug("message data: %s", (string)buffer);
this.parsePacketFromHost((string) buffer, isa.address);
}
this.parsePacketFromHost((string) buffer, isa.address);
private void parsePacketFromHost(string data, InetAddress host) {
// expecing an identity packet
var pkt = Packet.new_from_data(data);
if (pkt.pkt_type != Packet.IDENTITY) {
message("unexpected packet type %s from device %s",
pkt.pkt_type, host.to_string());
return;
}
private void parsePacketFromHost(string data, InetAddress host)
{
// expecing an identity packet
var pkt = Packet.new_from_data(data);
if (pkt.pkt_type != Packet.IDENTITY) {
message("unexpected packet type %s from device %s",
pkt.pkt_type, host.to_string());
return;
}
var dev = new DiscoveredDevice.from_identity(pkt, host);
message("connection from device: \'%s\', responds at: %s:%u",
dev.device_name, host.to_string(), dev.tcp_port);
device_found(dev);
var dev = new DiscoveredDevice.from_identity(pkt, host);
message("connection from device: \'%s\', responds at: %s:%u",
dev.device_name, host.to_string(), dev.tcp_port);
device_found(dev);
}
public void announce() {
var sock = new Socket(SocketFamily.IPV4,
SocketType.DATAGRAM,
SocketProtocol.UDP);
sock.broadcast = true;
try {
var sa = new InetSocketAddress(new InetAddress.from_string("255.255.255.255"),
1716);
var core = Core.instance();
var identity = Packet.new_identity(core.device_name,
core.device_id,
core.handlers.interfaces,
core.handlers.interfaces);
debug("identity: %s", identity.to_string());
sock.send_to(sa, identity.to_string().data);
} catch (Error e) {
warning("failed to send annoucement: %s", e.message);
}
sock.close();
}
}

+ 4
- 1
src/mconnect/packet.vala View File

@ -132,7 +132,8 @@ class Packet : GLib.Object {
string device_id,
string[] in_interfaces,
string[] out_interfaces,
string device_type = "desktop") {
string device_type = "desktop",
uint tcp_port = 1716) {
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("deviceName");
@ -147,6 +148,8 @@ class Packet : GLib.Object {
builder.add_string_value(string.joinv(",", out_interfaces));
builder.set_member_name("protocolVersion");
builder.add_int_value(PROTOCOL_VERSION);
builder.set_member_name("tcpPort");
builder.add_int_value(tcp_port);
builder.end_object();
Json.Object data_obj = builder.get_root().get_object();


Loading…
Cancel
Save