@ -0,0 +1,14 @@ | |||||
bin_PROGRAMS = mconnect | |||||
mconnect_SOURCES = src/main.vala \ | |||||
src/discovery.vala \ | |||||
src/packet.vala \ | |||||
src/device.vala \ | |||||
src/devicemanager.vala | |||||
mconnect_LDADD = $(MCONNECT_LIBS) | |||||
mconnect_CFLAGS = $(MCONNECT_CFLAGS) | |||||
VALAFLAGS = $(MCONNECT_VALAFLAGS) | |||||
@ -0,0 +1,56 @@ | |||||
# | |||||
# 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> | |||||
# | |||||
AC_PREREQ(2.61) | |||||
AC_INIT([mconnect], [0.1.0], [maciek.borzecki@gmail.com]) | |||||
AC_CONFIG_SRCDIR([src/main.vala]) | |||||
AC_CONFIG_AUX_DIR([.]) | |||||
AC_PROG_MAKE_SET | |||||
AM_INIT_AUTOMAKE([tar-pax foreign subdir-objects]) | |||||
AM_SILENT_RULES([yes]) | |||||
AM_MAINTAINER_MODE | |||||
# Checks for header files. | |||||
# AC_HEADER_STDC | |||||
# AC_CHECK_HEADERS([stdlib.h]) | |||||
# Checks for typedefs, structures, and compiler characteristics. | |||||
# AC_C_CONST | |||||
# Checks for programs. | |||||
AC_PROG_CC | |||||
AM_PROG_VALAC([0.7.0]) | |||||
AC_PROG_INSTALL | |||||
AC_SUBST(MCONNECT_VALAFLAGS, ["--pkg=json-glib-1.0 --pkg=gee-0.8"]) | |||||
# AC_SUBST(MCONNECT_VALAFLAGS, [--pkg=json-glib-1.0 --pkg=gee-0.8]) | |||||
PKG_CHECK_MODULES(MCONNECT, [glib-2.0, | |||||
gobject-2.0, | |||||
gio-2.0, | |||||
gio-unix-2.0, | |||||
json-glib-1.0, | |||||
gee-0.8 | |||||
]) | |||||
AC_SUBST(MCONNECT_CFLAGS) | |||||
AC_SUBST(MCONNECT_LIBS) | |||||
# Files to generate | |||||
AC_CONFIG_FILES([Makefile]) | |||||
# Output | |||||
AC_OUTPUT |
@ -0,0 +1,59 @@ | |||||
/* 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 Device : Object { | |||||
public string device_id { get; private set; default = ""; } | |||||
public string device_name { get; private set; default = ""; } | |||||
public string device_type { get; private set; default = ""; } | |||||
public uint protocol_version {get; private set; default = 5; } | |||||
public uint tcp_port {get; private set; default = 1714; } | |||||
public InetAddress host { get; private set; } | |||||
public bool paired { get; set; default = false; } | |||||
public Device() { | |||||
} | |||||
public Device.from_identity(Packet pkt, InetAddress host) { | |||||
var body = pkt.body; | |||||
this.host = host; | |||||
this.device_name = body.get_string_member("deviceName"); | |||||
this.device_id = body.get_string_member("deviceId"); | |||||
this.device_type = body.get_string_member("deviceType"); | |||||
this.protocol_version = (int) body.get_int_member("protocolVersion"); | |||||
this.tcp_port = (uint) body.get_int_member("tcpPort"); | |||||
debug("added new device: %s", this.to_string()); | |||||
} | |||||
~Device() { | |||||
} | |||||
public string to_unique_string() { | |||||
return ""; | |||||
} | |||||
public string to_string() { | |||||
return "%s-%s-%s-%u".printf(this.device_id, this.device_name, | |||||
this.device_type, this.protocol_version); | |||||
} | |||||
} |
@ -0,0 +1,34 @@ | |||||
/* 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> | |||||
*/ | |||||
using Gee; | |||||
class DeviceManager : GLib.Object | |||||
{ | |||||
private HashMap<string, Device> devices; | |||||
public DeviceManager() { | |||||
debug("device manager.."); | |||||
} | |||||
public void found_device(Device dev) { | |||||
debug("new device: %s", dev.to_string()); | |||||
} | |||||
} |
@ -0,0 +1,101 @@ | |||||
/* 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; | |||||
message("got %zd bytes from: %s:%u", read, | |||||
isa.address.to_string(), isa.port); | |||||
} catch (Error e) { | |||||
message("faile to receive packet: %s", e.message); | |||||
return; | |||||
} | |||||
message("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); | |||||
debug("connection from device: \'%s\', responds at: %s:%u", | |||||
dev.device_name, host.to_string(), dev.tcp_port); | |||||
device_found(dev); | |||||
} | |||||
} |
@ -0,0 +1,39 @@ | |||||
/* 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> | |||||
*/ | |||||
public static int main(string[] args) | |||||
{ | |||||
var loop = new MainLoop(); | |||||
var discovery = new Discovery(); | |||||
var manager = new DeviceManager(); | |||||
discovery.device_found.connect((disc, dev) => { | |||||
manager.found_device(dev); | |||||
}); | |||||
try { | |||||
discovery.listen(); | |||||
} catch (Error e) { | |||||
message("failed to setup device listener: %s", e.message); | |||||
return 1; | |||||
} | |||||
loop.run(); | |||||
return 0; | |||||
} |
@ -0,0 +1,58 @@ | |||||
/* 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> | |||||
*/ | |||||
using Json; | |||||
class Packet : GLib.Object { | |||||
public const string IDENTITY = "kdeconnect.identity"; | |||||
public const string PAIR = "kdeconnect.pair"; | |||||
public const string ENCRYPT = "kdeconnect.encrypt"; | |||||
public string pkt_type { get; private set; default = ""; } | |||||
public Json.Object body { get; private set; default = null; } | |||||
private Packet(string type, Json.Object body) { | |||||
this.pkt_type = type; | |||||
this.body = body; | |||||
} | |||||
public static Packet? new_from_data(string data) { | |||||
var jp = new Json.Parser(); | |||||
try { | |||||
jp.load_from_data(data, -1); | |||||
var root_obj = jp.get_root().get_object(); | |||||
var type = root_obj.get_string_member("type"); | |||||
debug("packet type: %s", type); | |||||
var body = root_obj.get_object_member("body"); | |||||
// var device_name = body.get_string_member("deviceName"); | |||||
// var port = (uint) body.get_int_member("tcpPort"); | |||||
return new Packet(type, body); | |||||
} catch (Error e) { | |||||
message("failed to parse message: \'%s\', error: %s", | |||||
data, e.message); | |||||
} | |||||
return null; | |||||
} | |||||
public string decrypt() { | |||||
return ""; | |||||
} | |||||
} |