diff --git a/src/device.vala b/src/device.vala index 0ce72db..0b35016 100644 --- a/src/device.vala +++ b/src/device.vala @@ -66,6 +66,32 @@ class Device : Object { debug("added new device: %s", this.to_string()); } + /** + * Constructs a new Device wrapper based on data read from device + * cache file. + * + * @cache: device cache file + * @name: device name + */ + public Device.from_cache(KeyFile cache, string name) { + debug("device from cache group %s", name); + + this.device_id = cache.get_string(name, "deviceId"); + this.device_name = cache.get_string(name, "deviceName"); + this.device_type = cache.get_string(name, "deviceType"); + this.protocol_version = cache.get_integer(name, "protocolVersion"); + this.tcp_port = (uint) cache.get_integer(name, "tcpPort"); + var last_ip_str = cache.get_string(name, "lastIPAddress"); + debug("last known address: %s:%u", last_ip_str, this.tcp_port); + + var host = new InetAddress.from_string(last_ip_str); + if (host == null) { + debug("failed to parse last known IP address (%s) for device %s", + last_ip_str, name); + } + this.host = host; + } + ~Device() { } @@ -82,6 +108,21 @@ class Device : Object { this.device_type, this.protocol_version); } + /** + * Dump device information to cache + * + * @cache: device cache + * @name: group name + */ + public void to_cache(KeyFile cache, string name) { + cache.set_string(name, "deviceId", this.device_id); + cache.set_string(name, "deviceName", this.device_name); + cache.set_string(name, "deviceType", this.device_type); + cache.set_integer(name, "protocolVersion", (int) this.protocol_version); + cache.set_integer(name, "tcpPort", (int) this.tcp_port); + cache.set_string(name, "lastIPAddress", this.host.to_string()); + } + private async void greet() { var core = Core.instance(); string host_name = Environment.get_host_name(); diff --git a/src/devicemanager.vala b/src/devicemanager.vala index 04335e5..e405a44 100644 --- a/src/devicemanager.vala +++ b/src/devicemanager.vala @@ -21,12 +21,82 @@ using Gee; class DeviceManager : GLib.Object { + public static const string DEVICES_CACHE_FILE = "devices"; + private HashMap devices; public DeviceManager() { debug("device manager.."); this.devices = new HashMap(); + + // TODO: check for network connectivity first, possibly pass + // this through the main loop + load_cache(); + } + + /** + * Obtain path to devices cache file + */ + private string get_cache_file() { + var cache_file = Path.build_filename(Core.get_cache_dir(), + DEVICES_CACHE_FILE); + debug("cache file: %s", cache_file); + + // make sure that cache dir exists + DirUtils.create_with_parents(Core.get_cache_dir(), + 0700); + + return cache_file; + } + + /** + * Load known devices from cache and attempt pairing. + */ + private void load_cache() { + debug("try loading devices from device cache"); + + var cache_file = get_cache_file(); + + var kf = new KeyFile(); + try { + kf.load_from_file(cache_file, KeyFileFlags.NONE); + + string[] groups = kf.get_groups(); + + foreach (string group in groups) { + var dev = new Device.from_cache(kf, group); + debug("device %s from cache", dev.to_string()); + found_device(dev); + } + } catch (Error e) { + debug("error loading cache file: %s", e.message); + } + } + + /** + * Update contents of device cache + */ + private void update_cache() { + debug("update devices cache"); + + if (devices.size == 0) + return; + + var kf = new KeyFile(); + + foreach (Device dev in devices.values) { + dev.to_cache(kf, dev.device_name); + } + + try { + debug("saving to cache"); + FileUtils.set_contents(get_cache_file(), + kf.to_data()); + } catch (FileError e) { + debug("failed to save to cache file %s: %s", + get_cache_file(), e.message); + } } public void found_device(Device dev) { @@ -56,6 +126,10 @@ class DeviceManager : GLib.Object var known_dev = this.devices.@get(unique); known_dev.activate_from_device(dev); } + + // device in whitelist and added to currently used devices, so + // it's ok to update the device cache + update_cache(); } private bool device_allowed(Device dev) {