mconnect - KDE Connect protocol implementation in Vala/C
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

100 lines
2.7 KiB

/* 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>
*/
class Discovery : GLib.Object
{
private Socket socket = null;
public signal void device_found(Device dev);
public Discovery() {
}
~Discovery() {
debug("cleaning up discovery...");
if (this.socket != null) {
this.socket.close();
}
}
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());
}
private void incomingPacket() {
debug("incoming packet");
uint8 buffer[4096];
SocketAddress sa;
InetSocketAddress isa;
try {
ssize_t read = this.socket.receive_from(out sa, buffer);
isa = (InetSocketAddress)sa;
debug("got %zd bytes from: %s:%u", read,
isa.address.to_string(), isa.port);
} catch (Error e) {
message("failed to receive packet: %s", e.message);
return;
}
debug("message data: %s", (string)buffer);
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;
}
var dev = new Device.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);
}
}