diff options
Diffstat (limited to 'src/lib/bluez')
76 files changed, 9323 insertions, 3291 deletions
diff --git a/src/lib/bluez/adapter.c b/src/lib/bluez/adapter.c index 00ad300..6bdeda3 100644 --- a/src/lib/bluez/adapter.c +++ b/src/lib/bluez/adapter.c @@ -24,358 +24,83 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif - -#include <string.h> - +#include <gio/gio.h> #include <glib.h> -#include <dbus/dbus-glib.h> +#include <string.h> #include "../dbus-common.h" -#include "../marshallers.h" +#include "../properties.h" #include "adapter.h" #define ADAPTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ADAPTER_TYPE, AdapterPrivate)) struct _AdapterPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gchar *address; - guint32 class; - GPtrArray *devices; - gboolean discoverable; - guint32 discoverable_timeout; - gboolean discovering; - gchar *name; - gboolean pairable; - guint32 pairable_timeout; - gboolean powered; - gchar **uuids; - - /* Async calls */ - DBusGProxyCall *create_paired_device_call; + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; }; -G_DEFINE_TYPE(Adapter, adapter, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE(Adapter, adapter, G_TYPE_OBJECT); enum { PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_ADDRESS, /* readonly */ - PROP_CLASS, /* readonly */ - PROP_DEVICES, /* readonly */ - PROP_DISCOVERABLE, /* readwrite */ - PROP_DISCOVERABLE_TIMEOUT, /* readwrite */ - PROP_DISCOVERING, /* readonly */ - PROP_NAME, /* readwrite */ - PROP_PAIRABLE, /* readwrite */ - PROP_PAIRABLE_TIMEOUT, /* readwrite */ - PROP_POWERED, /* readwrite */ - PROP_UUIDS /* readonly */ + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ }; static void _adapter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void _adapter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -enum { - DEVICE_CREATED, - DEVICE_DISAPPEARED, - DEVICE_FOUND, - DEVICE_REMOVED, - PROPERTY_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void device_created_handler(DBusGProxy *dbus_g_proxy, const gchar *device, gpointer data); -static void device_disappeared_handler(DBusGProxy *dbus_g_proxy, const gchar *address, gpointer data); -static void device_found_handler(DBusGProxy *dbus_g_proxy, const gchar *address, GHashTable *values, gpointer data); -static void device_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *device, gpointer data); -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); +static void _adapter_create_gdbus_proxy(Adapter *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); static void adapter_dispose(GObject *gobject) { Adapter *self = ADAPTER(gobject); - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "DeviceCreated", G_CALLBACK(device_created_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "DeviceDisappeared", G_CALLBACK(device_disappeared_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "DeviceFound", G_CALLBACK(device_found_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "DeviceRemoved", G_CALLBACK(device_removed_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self); - - /* Properties free */ - g_free(self->priv->address); - g_ptr_array_unref(self->priv->devices); - g_free(self->priv->name); - g_strfreev(self->priv->uuids); - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); /* Chain up to the parent class */ G_OBJECT_CLASS(adapter_parent_class)->dispose(gobject); } +static void adapter_finalize (GObject *gobject) +{ + Adapter *self = ADAPTER(gobject); + G_OBJECT_CLASS(adapter_parent_class)->finalize(gobject); +} + static void adapter_class_init(AdapterClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->dispose = adapter_dispose; - g_type_class_add_private(klass, sizeof(AdapterPrivate)); - /* Properties registration */ - GParamSpec *pspec; + GParamSpec *pspec = NULL; gobject_class->get_property = _adapter_get_property; gobject_class->set_property = _adapter_set_property; - + /* object DBusObjectPath [readwrite, construct only] */ pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); - - /* string Address [readonly] */ - pspec = g_param_spec_string("Address", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_ADDRESS, pspec); - - /* uint32 Class [readonly] */ - pspec = g_param_spec_uint("Class", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_CLASS, pspec); - - /* array{object} Devices [readonly] */ - pspec = g_param_spec_boxed("Devices", NULL, NULL, G_TYPE_PTR_ARRAY, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_DEVICES, pspec); - - /* boolean Discoverable [readwrite] */ - pspec = g_param_spec_boolean("Discoverable", NULL, NULL, FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_DISCOVERABLE, pspec); - - /* uint32 DiscoverableTimeout [readwrite] */ - pspec = g_param_spec_uint("DiscoverableTimeout", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_DISCOVERABLE_TIMEOUT, pspec); - - /* boolean Discovering [readonly] */ - pspec = g_param_spec_boolean("Discovering", NULL, NULL, FALSE, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_DISCOVERING, pspec); - - /* string Name [readwrite] */ - pspec = g_param_spec_string("Name", NULL, NULL, NULL, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_NAME, pspec); - - /* boolean Pairable [readwrite] */ - pspec = g_param_spec_boolean("Pairable", NULL, NULL, FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_PAIRABLE, pspec); - - /* uint32 PairableTimeout [readwrite] */ - pspec = g_param_spec_uint("PairableTimeout", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_PAIRABLE_TIMEOUT, pspec); - - /* boolean Powered [readwrite] */ - pspec = g_param_spec_boolean("Powered", NULL, NULL, FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_POWERED, pspec); - - /* array{string} UUIDs [readonly] */ - pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_STRV, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_UUIDS, pspec); - - /* Signals registation */ - signals[DEVICE_CREATED] = g_signal_new("DeviceCreated", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[DEVICE_DISAPPEARED] = g_signal_new("DeviceDisappeared", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[DEVICE_FOUND] = g_signal_new("DeviceFound", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_HASH_TABLE); - - signals[DEVICE_REMOVED] = g_signal_new("DeviceRemoved", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[PROPERTY_CHANGED] = g_signal_new("PropertyChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); + if (pspec) + g_param_spec_unref(pspec); } static void adapter_init(Adapter *self) { - self->priv = ADAPTER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - /* Async calls init */ - self->priv->create_paired_device_call = NULL; - + self->priv = adapter_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; g_assert(system_conn != NULL); } -static void adapter_post_init(Adapter *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", ADAPTER_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", ADAPTER_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, ADAPTER_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* DeviceCreated(object device) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DeviceCreated", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DeviceCreated", G_CALLBACK(device_created_handler), self, NULL); - - /* DeviceDisappeared(string address) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DeviceDisappeared", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DeviceDisappeared", G_CALLBACK(device_disappeared_handler), self, NULL); - - /* DeviceFound(string address, dict values) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DeviceFound", G_TYPE_STRING, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DeviceFound", G_CALLBACK(device_found_handler), self, NULL); - - /* DeviceRemoved(object device) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DeviceRemoved", G_CALLBACK(device_removed_handler), self, NULL); - - /* PropertyChanged(string name, variant value) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self, NULL); - - /* Properties init */ - GHashTable *properties = adapter_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* string Address [readonly] */ - if (g_hash_table_lookup(properties, "Address")) { - self->priv->address = g_value_dup_string(g_hash_table_lookup(properties, "Address")); - } else { - self->priv->address = g_strdup("undefined"); - } - - /* uint32 Class [readonly] */ - if (g_hash_table_lookup(properties, "Class")) { - self->priv->class = g_value_get_uint(g_hash_table_lookup(properties, "Class")); - } else { - self->priv->class = 0; - } - - /* array{object} Devices [readonly] */ - if (g_hash_table_lookup(properties, "Devices")) { - self->priv->devices = g_value_dup_boxed(g_hash_table_lookup(properties, "Devices")); - } else { - self->priv->devices = g_ptr_array_new(); - } - - /* boolean Discoverable [readwrite] */ - if (g_hash_table_lookup(properties, "Discoverable")) { - self->priv->discoverable = g_value_get_boolean(g_hash_table_lookup(properties, "Discoverable")); - } else { - self->priv->discoverable = FALSE; - } - - /* uint32 DiscoverableTimeout [readwrite] */ - if (g_hash_table_lookup(properties, "DiscoverableTimeout")) { - self->priv->discoverable_timeout = g_value_get_uint(g_hash_table_lookup(properties, "DiscoverableTimeout")); - } else { - self->priv->discoverable_timeout = 0; - } - - /* boolean Discovering [readonly] */ - if (g_hash_table_lookup(properties, "Discovering")) { - self->priv->discovering = g_value_get_boolean(g_hash_table_lookup(properties, "Discovering")); - } else { - self->priv->discovering = FALSE; - } - - /* string Name [readwrite] */ - if (g_hash_table_lookup(properties, "Name")) { - self->priv->name = g_value_dup_string(g_hash_table_lookup(properties, "Name")); - } else { - self->priv->name = g_strdup("undefined"); - } - - /* boolean Pairable [readwrite] */ - if (g_hash_table_lookup(properties, "Pairable")) { - self->priv->pairable = g_value_get_boolean(g_hash_table_lookup(properties, "Pairable")); - } else { - self->priv->pairable = FALSE; - } - - /* uint32 PairableTimeout [readwrite] */ - if (g_hash_table_lookup(properties, "PairableTimeout")) { - self->priv->pairable_timeout = g_value_get_uint(g_hash_table_lookup(properties, "PairableTimeout")); - } else { - self->priv->pairable_timeout = 0; - } - - /* boolean Powered [readwrite] */ - if (g_hash_table_lookup(properties, "Powered")) { - self->priv->powered = g_value_get_boolean(g_hash_table_lookup(properties, "Powered")); - } else { - self->priv->powered = FALSE; - } - - /* array{string} UUIDs [readonly] */ - if (g_hash_table_lookup(properties, "UUIDs")) { - self->priv->uuids = (gchar **) g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs")); - } else { - self->priv->uuids = g_new0(char *, 1); - self->priv->uuids[0] = NULL; - } - - g_hash_table_unref(properties); -} - static void _adapter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { Adapter *self = ADAPTER(object); @@ -385,50 +110,6 @@ static void _adapter_get_property(GObject *object, guint property_id, GValue *va g_value_set_string(value, adapter_get_dbus_object_path(self)); break; - case PROP_ADDRESS: - g_value_set_string(value, adapter_get_address(self)); - break; - - case PROP_CLASS: - g_value_set_uint(value, adapter_get_class(self)); - break; - - case PROP_DEVICES: - g_value_set_boxed(value, adapter_get_devices(self)); - break; - - case PROP_DISCOVERABLE: - g_value_set_boolean(value, adapter_get_discoverable(self)); - break; - - case PROP_DISCOVERABLE_TIMEOUT: - g_value_set_uint(value, adapter_get_discoverable_timeout(self)); - break; - - case PROP_DISCOVERING: - g_value_set_boolean(value, adapter_get_discovering(self)); - break; - - case PROP_NAME: - g_value_set_string(value, adapter_get_name(self)); - break; - - case PROP_PAIRABLE: - g_value_set_boolean(value, adapter_get_pairable(self)); - break; - - case PROP_PAIRABLE_TIMEOUT: - g_value_set_uint(value, adapter_get_pairable_timeout(self)); - break; - - case PROP_POWERED: - g_value_set_boolean(value, adapter_get_powered(self)); - break; - - case PROP_UUIDS: - g_value_set_boxed(value, adapter_get_uuids(self)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -442,31 +123,8 @@ static void _adapter_set_property(GObject *object, guint property_id, const GVal switch (property_id) { case PROP_DBUS_OBJECT_PATH: - adapter_post_init(self, g_value_get_string(value)); - break; - - case PROP_DISCOVERABLE: - adapter_set_property(self, "Discoverable", value, &error); - break; - - case PROP_DISCOVERABLE_TIMEOUT: - adapter_set_property(self, "DiscoverableTimeout", value, &error); - break; - - case PROP_NAME: - adapter_set_property(self, "Name", value, &error); - break; - - case PROP_PAIRABLE: - adapter_set_property(self, "Pairable", value, &error); - break; - - case PROP_PAIRABLE_TIMEOUT: - adapter_set_property(self, "PairableTimeout", value, &error); - break; - - case PROP_POWERED: - adapter_set_property(self, "Powered", value, &error); + self->priv->object_path = g_value_dup_string(value); + _adapter_create_gdbus_proxy(self, ADAPTER_DBUS_SERVICE, self->priv->object_path, &error); break; default: @@ -474,390 +132,260 @@ static void _adapter_set_property(GObject *object, guint property_id, const GVal break; } - if (error != NULL) { + if (error != NULL) g_critical("%s", error->message); - } - g_assert(error == NULL); -} - -static void adapter_async_notify_callback(DBusGProxy *proxy, DBusGProxyCall *call, gpointer data) -{ - gpointer *p = data; - void (*AsyncNotifyFunc)(gpointer data) = p[0]; - (*AsyncNotifyFunc)(p[1]); - g_free(p); -} - -/* Methods */ - -/* void CancelDeviceCreation(string address) */ -void adapter_cancel_device_creation(Adapter *self, const gchar *address, GError **error) -{ - g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "CancelDeviceCreation", error, G_TYPE_STRING, address, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* object CreateDevice(string address) */ -gchar *adapter_create_device(Adapter *self, const gchar *address, GError **error) -{ - g_assert(ADAPTER_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateDevice", error, G_TYPE_STRING, address, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); - return ret; + g_assert(error == NULL); } -/* object CreatePairedDevice(string address, object agent, string capability) [async] */ -void adapter_create_paired_device_begin(Adapter *self, void (*AsyncNotifyFunc)(gpointer data), gpointer data, const gchar *address, const gchar *agent, const gchar *capability) +/* Constructor */ +Adapter *adapter_new(const gchar *dbus_object_path) { - g_assert(ADAPTER_IS(self)); - g_assert(self->priv->create_paired_device_call == NULL); - - gpointer *p = g_new0(gpointer, 2); - p[0] = AsyncNotifyFunc; - p[1] = data; - - self->priv->create_paired_device_call = dbus_g_proxy_begin_call(self->priv->dbus_g_proxy, "CreatePairedDevice", (DBusGProxyCallNotify) adapter_async_notify_callback, p, NULL, G_TYPE_STRING, address, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_STRING, capability, G_TYPE_INVALID); + return g_object_new(ADAPTER_TYPE, "DBusObjectPath", dbus_object_path, NULL); } -gchar *adapter_create_paired_device_end(Adapter *self, GError **error) +/* Private DBus proxy creation */ +static void _adapter_create_gdbus_proxy(Adapter *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) { g_assert(ADAPTER_IS(self)); - g_assert(self->priv->create_paired_device_call != NULL); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, ADAPTER_DBUS_INTERFACE, NULL, error); - gchar *ret = NULL; - dbus_g_proxy_end_call(self->priv->dbus_g_proxy, self->priv->create_paired_device_call, error, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); - self->priv->create_paired_device_call = NULL; + if(self->priv->proxy == NULL) + return; - return ret; + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); } -/* object FindDevice(string address) */ -gchar *adapter_find_device(Adapter *self, const gchar *address, GError **error) -{ - g_assert(ADAPTER_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "FindDevice", error, G_TYPE_STRING, address, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); - - return ret; -} - -/* dict GetProperties() */ -GHashTable *adapter_get_properties(Adapter *self, GError **error) -{ - g_assert(ADAPTER_IS(self)); - - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); - - return ret; -} +/* Methods */ -/* void RegisterAgent(object agent, string capability) */ -void adapter_register_agent(Adapter *self, const gchar *agent, const gchar *capability, GError **error) +/* Get DBus object path */ +const gchar *adapter_get_dbus_object_path(Adapter *self) { g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "RegisterAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_STRING, capability, G_TYPE_INVALID, G_TYPE_INVALID); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); } /* void RemoveDevice(object device) */ void adapter_remove_device(Adapter *self, const gchar *device, GError **error) { g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoveDevice", error, DBUS_TYPE_G_OBJECT_PATH, device, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void SetProperty(string name, variant value) */ -void adapter_set_property(Adapter *self, const gchar *name, const GValue *value, GError **error) -{ - g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "SetProperty", error, G_TYPE_STRING, name, G_TYPE_VALUE, value, G_TYPE_INVALID, G_TYPE_INVALID); + g_dbus_proxy_call_sync(self->priv->proxy, "RemoveDevice", g_variant_new ("(o)", device), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } /* void StartDiscovery() */ void adapter_start_discovery(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "StartDiscovery", error, G_TYPE_INVALID, G_TYPE_INVALID); + g_dbus_proxy_call_sync(self->priv->proxy, "StartDiscovery", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } /* void StopDiscovery() */ void adapter_stop_discovery(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "StopDiscovery", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void UnregisterAgent(object agent) */ -void adapter_unregister_agent(Adapter *self, const gchar *agent, GError **error) -{ - g_assert(ADAPTER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "UnregisterAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); + g_dbus_proxy_call_sync(self->priv->proxy, "StopDiscovery", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } /* Properties access methods */ -const gchar *adapter_get_dbus_object_path(Adapter *self) +GVariant *adapter_get_properties(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, ADAPTER_DBUS_INTERFACE, error); } -const gchar *adapter_get_address(Adapter *self) +void adapter_set_property(Adapter *self, const gchar *name, const GVariant *value, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->address; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, name, value, error); } -const guint32 adapter_get_class(Adapter *self) +const gchar *adapter_get_address(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->class; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Address", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const GPtrArray *adapter_get_devices(Adapter *self) +const gchar *adapter_get_alias(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->devices; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Alias", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const gboolean adapter_get_discoverable(Adapter *self) +void adapter_set_alias(Adapter *self, const gchar *value, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->discoverable; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Alias", g_variant_new_string(value), error); } -void adapter_set_discoverable(Adapter *self, const gboolean value) +guint32 adapter_get_class(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_BOOLEAN); - g_value_set_boolean(&t, value); - adapter_set_property(self, "Discoverable", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Class", error); + if(prop == NULL) + return 0; + guint32 ret = g_variant_get_uint32(prop); + g_variant_unref(prop); + return ret; } -const guint32 adapter_get_discoverable_timeout(Adapter *self) +gboolean adapter_get_discoverable(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->discoverable_timeout; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Discoverable", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -void adapter_set_discoverable_timeout(Adapter *self, const guint32 value) +void adapter_set_discoverable(Adapter *self, const gboolean value, GError **error) { g_assert(ADAPTER_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_UINT); - g_value_set_uint(&t, value); - adapter_set_property(self, "DiscoverableTimeout", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Discoverable", g_variant_new_boolean(value), error); } -const gboolean adapter_get_discovering(Adapter *self) +guint32 adapter_get_discoverable_timeout(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->discovering; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "DiscoverableTimeout", error); + if(prop == NULL) + return 0; + guint32 ret = g_variant_get_uint32(prop); + g_variant_unref(prop); + return ret; } -const gchar *adapter_get_name(Adapter *self) +void adapter_set_discoverable_timeout(Adapter *self, const guint32 value, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->name; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, "DiscoverableTimeout", g_variant_new_uint32(value), error); } -void adapter_set_name(Adapter *self, const gchar *value) +gboolean adapter_get_discovering(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_STRING); - g_value_set_string(&t, value); - adapter_set_property(self, "Name", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Discovering", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -const gboolean adapter_get_pairable(Adapter *self) +const gchar *adapter_get_modalias(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->pairable; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Modalias", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -void adapter_set_pairable(Adapter *self, const gboolean value) +const gchar *adapter_get_name(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_BOOLEAN); - g_value_set_boolean(&t, value); - adapter_set_property(self, "Pairable", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Name", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const guint32 adapter_get_pairable_timeout(Adapter *self) +gboolean adapter_get_pairable(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->pairable_timeout; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Pairable", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -void adapter_set_pairable_timeout(Adapter *self, const guint32 value) +void adapter_set_pairable(Adapter *self, const gboolean value, GError **error) { g_assert(ADAPTER_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_UINT); - g_value_set_uint(&t, value); - adapter_set_property(self, "PairableTimeout", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Pairable", g_variant_new_boolean(value), error); } -const gboolean adapter_get_powered(Adapter *self) +guint32 adapter_get_pairable_timeout(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->powered; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "PairableTimeout", error); + if(prop == NULL) + return 0; + guint32 ret = g_variant_get_uint32(prop); + g_variant_unref(prop); + return ret; } -void adapter_set_powered(Adapter *self, const gboolean value) +void adapter_set_pairable_timeout(Adapter *self, const guint32 value, GError **error) { g_assert(ADAPTER_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_BOOLEAN); - g_value_set_boolean(&t, value); - adapter_set_property(self, "Powered", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, "PairableTimeout", g_variant_new_uint32(value), error); } -const gchar **adapter_get_uuids(Adapter *self) +gboolean adapter_get_powered(Adapter *self, GError **error) { g_assert(ADAPTER_IS(self)); - - return self->priv->uuids; -} - -/* Signals handlers */ -static void device_created_handler(DBusGProxy *dbus_g_proxy, const gchar *device, gpointer data) -{ - Adapter *self = ADAPTER(data); - - g_signal_emit(self, signals[DEVICE_CREATED], 0, device); -} - -static void device_disappeared_handler(DBusGProxy *dbus_g_proxy, const gchar *address, gpointer data) -{ - Adapter *self = ADAPTER(data); - - g_signal_emit(self, signals[DEVICE_DISAPPEARED], 0, address); -} - -static void device_found_handler(DBusGProxy *dbus_g_proxy, const gchar *address, GHashTable *values, gpointer data) -{ - Adapter *self = ADAPTER(data); - - g_signal_emit(self, signals[DEVICE_FOUND], 0, address, values); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Powered", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -static void device_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *device, gpointer data) +void adapter_set_powered(Adapter *self, const gboolean value, GError **error) { - Adapter *self = ADAPTER(data); - - g_signal_emit(self, signals[DEVICE_REMOVED], 0, device); + g_assert(ADAPTER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, ADAPTER_DBUS_INTERFACE, "Powered", g_variant_new_boolean(value), error); } -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +const gchar **adapter_get_uuids(Adapter *self, GError **error) { - Adapter *self = ADAPTER(data); - - if (g_strcmp0(name, "Address") == 0) { - g_free(self->priv->address); - self->priv->address = g_value_dup_string(value); - } else if (g_strcmp0(name, "Class") == 0) { - self->priv->class = g_value_get_uint(value); - } else if (g_strcmp0(name, "Devices") == 0) { - g_ptr_array_unref(self->priv->devices); - self->priv->devices = g_value_dup_boxed(value); - } else if (g_strcmp0(name, "Discoverable") == 0) { - self->priv->discoverable = g_value_get_boolean(value); - } else if (g_strcmp0(name, "DiscoverableTimeout") == 0) { - self->priv->discoverable_timeout = g_value_get_uint(value); - } else if (g_strcmp0(name, "Discovering") == 0) { - self->priv->discovering = g_value_get_boolean(value); - } else if (g_strcmp0(name, "Name") == 0) { - g_free(self->priv->name); - self->priv->name = g_value_dup_string(value); - } else if (g_strcmp0(name, "Pairable") == 0) { - self->priv->pairable = g_value_get_boolean(value); - } else if (g_strcmp0(name, "PairableTimeout") == 0) { - self->priv->pairable_timeout = g_value_get_uint(value); - } else if (g_strcmp0(name, "Powered") == 0) { - self->priv->powered = g_value_get_boolean(value); - } else if (g_strcmp0(name, "UUIDs") == 0) { - g_strfreev(self->priv->uuids); - self->priv->uuids = (gchar **) g_value_dup_boxed(value); - } - - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); + g_assert(ADAPTER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, ADAPTER_DBUS_INTERFACE, "UUIDs", error); + if(prop == NULL) + return NULL; + const gchar **ret = g_variant_get_strv(prop, NULL); + g_variant_unref(prop); + return ret; } diff --git a/src/lib/bluez/adapter.h b/src/lib/bluez/adapter.h index 22ee02f..97de77d 100644 --- a/src/lib/bluez/adapter.h +++ b/src/lib/bluez/adapter.h @@ -24,9 +24,14 @@ #ifndef __ADAPTER_H #define __ADAPTER_H +#ifdef __cplusplus +extern "C" { +#endif + #include <glib-object.h> -#define ADAPTER_DBUS_INTERFACE "org.bluez.Adapter" +#define ADAPTER_DBUS_SERVICE "org.bluez" +#define ADAPTER_DBUS_INTERFACE "org.bluez.Adapter1" /* * Type macros @@ -57,39 +62,44 @@ struct _AdapterClass { GType adapter_get_type(void) G_GNUC_CONST; /* + * Constructor + */ +Adapter *adapter_new(const gchar *dbus_object_path); + +/* * Method definitions */ -void adapter_cancel_device_creation(Adapter *self, const gchar *address, GError **error); -gchar *adapter_create_device(Adapter *self, const gchar *address, GError **error); -void adapter_create_paired_device_begin(Adapter *self, void (*AsyncNotifyFunc)(gpointer data), gpointer data, const gchar *address, const gchar *agent, const gchar *capability); -gchar *adapter_create_paired_device_end(Adapter *self, GError **error); -gchar *adapter_find_device(Adapter *self, const gchar *address, GError **error); -GHashTable *adapter_get_properties(Adapter *self, GError **error); -void adapter_register_agent(Adapter *self, const gchar *agent, const gchar *capability, GError **error); +const gchar *adapter_get_dbus_object_path(Adapter *self); + void adapter_remove_device(Adapter *self, const gchar *device, GError **error); -void adapter_set_property(Adapter *self, const gchar *name, const GValue *value, GError **error); void adapter_start_discovery(Adapter *self, GError **error); void adapter_stop_discovery(Adapter *self, GError **error); -void adapter_unregister_agent(Adapter *self, const gchar *agent, GError **error); -const gchar *adapter_get_dbus_object_path(Adapter *self); -const gchar *adapter_get_address(Adapter *self); -const guint32 adapter_get_class(Adapter *self); -const GPtrArray *adapter_get_devices(Adapter *self); -const gboolean adapter_get_discoverable(Adapter *self); -void adapter_set_discoverable(Adapter *self, const gboolean value); -const guint32 adapter_get_discoverable_timeout(Adapter *self); -void adapter_set_discoverable_timeout(Adapter *self, const guint32 value); -const gboolean adapter_get_discovering(Adapter *self); -const gchar *adapter_get_name(Adapter *self); -void adapter_set_name(Adapter *self, const gchar *value); -const gboolean adapter_get_pairable(Adapter *self); -void adapter_set_pairable(Adapter *self, const gboolean value); -const guint32 adapter_get_pairable_timeout(Adapter *self); -void adapter_set_pairable_timeout(Adapter *self, const guint32 value); -const gboolean adapter_get_powered(Adapter *self); -void adapter_set_powered(Adapter *self, const gboolean value); -const gchar **adapter_get_uuids(Adapter *self); +GVariant *adapter_get_properties(Adapter *self, GError **error); +void adapter_set_property(Adapter *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *adapter_get_address(Adapter *self, GError **error); +const gchar *adapter_get_alias(Adapter *self, GError **error); +void adapter_set_alias(Adapter *self, const gchar *value, GError **error); +guint32 adapter_get_class(Adapter *self, GError **error); +gboolean adapter_get_discoverable(Adapter *self, GError **error); +void adapter_set_discoverable(Adapter *self, const gboolean value, GError **error); +guint32 adapter_get_discoverable_timeout(Adapter *self, GError **error); +void adapter_set_discoverable_timeout(Adapter *self, const guint32 value, GError **error); +gboolean adapter_get_discovering(Adapter *self, GError **error); +const gchar *adapter_get_modalias(Adapter *self, GError **error); +const gchar *adapter_get_name(Adapter *self, GError **error); +gboolean adapter_get_pairable(Adapter *self, GError **error); +void adapter_set_pairable(Adapter *self, const gboolean value, GError **error); +guint32 adapter_get_pairable_timeout(Adapter *self, GError **error); +void adapter_set_pairable_timeout(Adapter *self, const guint32 value, GError **error); +gboolean adapter_get_powered(Adapter *self, GError **error); +void adapter_set_powered(Adapter *self, const gboolean value, GError **error); +const gchar **adapter_get_uuids(Adapter *self, GError **error); + +#ifdef __cplusplus +} +#endif #endif /* __ADAPTER_H */ diff --git a/src/lib/bluez/agent.c b/src/lib/bluez/agent.c deleted file mode 100644 index dc29706..0000000 --- a/src/lib/bluez/agent.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010-2011 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <string.h> - -#include <glib.h> -#include <dbus/dbus-glib.h> - -#include "../dbus-common.h" -#include "../helpers.h" - -#include "device.h" -#include "agent.h" - -#define AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), AGENT_TYPE, AgentPrivate)) - -struct _AgentPrivate { - /* Properties */ - GHashTable *pin_hash_table; /* (extern) name|mac -> pin hash table */ - gboolean interactive; /* Interactive mode */ -}; - -G_DEFINE_TYPE(Agent, agent, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_PIN_HASH_TABLE, /* write, construct only */ - PROP_INTERACTIVE /* write, construct only */ -}; - -static void _agent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _agent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -enum { - AGENT_RELEASED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void agent_dispose(GObject *gobject) -{ - Agent *self = AGENT(gobject); - - dbus_g_connection_unregister_g_object(system_conn, gobject); - - /* Chain up to the parent class */ - G_OBJECT_CLASS(agent_parent_class)->dispose(gobject); -} - -static void agent_class_init(AgentClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = agent_dispose; - - g_type_class_add_private(klass, sizeof(AgentPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _agent_get_property; - gobject_class->set_property = _agent_set_property; - - /* object PinHashTable [write, construct only] */ - pspec = g_param_spec_boxed("PinHashTable", "pin_hash_table", "Name|MAC -> PIN hash table", G_TYPE_HASH_TABLE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property(gobject_class, PROP_PIN_HASH_TABLE, pspec); - - /* boolean Interactive [write, construct only] */ - pspec = g_param_spec_boolean("Interactive", "interactive", "Interactive mode", TRUE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property(gobject_class, PROP_INTERACTIVE, pspec); - - /* Signals registation */ - signals[AGENT_RELEASED] = g_signal_new("AgentReleased", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void agent_init(Agent *self) -{ - self->priv = AGENT_GET_PRIVATE(self); - - g_assert(system_conn != NULL); - - /* Properties init */ - self->priv->pin_hash_table = NULL; - self->priv->interactive = TRUE; - - dbus_g_connection_register_g_object(system_conn, AGENT_DBUS_PATH, G_OBJECT(self)); -} - -static void _agent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - Agent *self = AGENT(object); - - switch (property_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _agent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - Agent *self = AGENT(object); - - switch (property_id) { - case PROP_PIN_HASH_TABLE: - self->priv->pin_hash_table = g_value_get_boxed(value); - break; - - case PROP_INTERACTIVE: - self->priv->interactive = g_value_get_boolean(value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -/* Methods */ - -static const gchar *find_device_pin(Agent *self, Device *device_obj) -{ - if (self->priv->pin_hash_table) { - const gchar *pin_by_addr = g_hash_table_lookup(self->priv->pin_hash_table, device_get_address(device_obj)); - const gchar *pin_by_alias = g_hash_table_lookup(self->priv->pin_hash_table, device_get_alias(device_obj)); - const gchar *pin_all = g_hash_table_lookup(self->priv->pin_hash_table, "*"); - - if (pin_by_addr) - return pin_by_addr; - else if (pin_by_alias) - return pin_by_alias; - else if (pin_all) - return pin_all; - } - - return NULL; -} - -gboolean agent_release(Agent *self, GError **error) -{ - g_signal_emit(self, signals[AGENT_RELEASED], 0); - - return TRUE; -} - -gboolean agent_request_pin_code(Agent *self, const gchar *device, gchar **ret, GError **error) -{ - Device *device_obj = g_object_new(DEVICE_TYPE, "DBusObjectPath", device, NULL); - const gchar *pin = find_device_pin(self, device_obj); - - if (self->priv->interactive) - g_print("Device: %s (%s)\n", device_get_alias(device_obj), device_get_address(device_obj)); - - g_object_unref(device_obj); - - /* Try to use found PIN */ - if (pin != NULL) { - if (self->priv->interactive) - g_print("PIN found\n"); - - *ret = g_new0(gchar, 17); - sscanf(pin, "%16s", *ret); - - return TRUE; - } else if (self->priv->interactive) { - g_print("Enter PIN code: "); - *ret = g_new0(gchar, 17); - errno = 0; - if (scanf("%16s", *ret) == EOF && errno) { - g_warning("%s\n", strerror(errno)); - } - - return TRUE; - } - - return FALSE; // Request rejected -} - -gboolean agent_request_passkey(Agent *self, const gchar *device, guint *ret, GError **error) -{ - Device *device_obj = g_object_new(DEVICE_TYPE, "DBusObjectPath", device, NULL); - const gchar *pin = find_device_pin(self, device_obj); - - if (self->priv->interactive) - g_print("Device: %s (%s)\n", device_get_alias(device_obj), device_get_address(device_obj)); - - g_object_unref(device_obj); - - /* Try to use found PIN */ - if (pin != NULL) { - if (self->priv->interactive) - g_print("Passkey found\n"); - - sscanf(pin, "%u", ret); - - return TRUE; - } else if (self->priv->interactive) { - g_print("Enter passkey: "); - errno = 0; - if (scanf("%u", ret) == EOF && errno) { - g_warning("%s\n", strerror(errno)); - } - - return TRUE; - } - - return FALSE; // Request rejected -} - -gboolean agent_display_passkey(Agent *self, const gchar *device, guint passkey, guint8 entered, GError **error) -{ - Device *device_obj = g_object_new(DEVICE_TYPE, "DBusObjectPath", device, NULL); - const gchar *pin = find_device_pin(self, device_obj); - - if (self->priv->interactive) - g_print("Device: %s (%s)\n", device_get_alias(device_obj), device_get_address(device_obj)); - - g_object_unref(device_obj); - - if (self->priv->interactive) { - g_print("Passkey: %u, entered: %u\n", passkey, entered); - - return TRUE; - } else if (pin != NULL) { - /* OK, device found */ - return TRUE; - } - - return FALSE; // Request rejected -} - -gboolean agent_request_confirmation(Agent *self, const gchar *device, guint passkey, GError **error) -{ - Device *device_obj = g_object_new(DEVICE_TYPE, "DBusObjectPath", device, NULL); - const gchar *pin = find_device_pin(self, device_obj); - - if (self->priv->interactive) - g_print("Device: %s (%s)\n", device_get_alias(device_obj), device_get_address(device_obj)); - - g_object_unref(device_obj); - - /* Try to use found PIN */ - if (pin != NULL) { - guint passkey_t; - sscanf(pin, "%u", &passkey_t); - - if (g_strcmp0(pin, "*") == 0 || passkey_t == passkey) { - if (self->priv->interactive) - g_print("Passkey confirmed\n"); - - return TRUE; - } else { - if (self->priv->interactive) - g_print("Passkey rejected\n"); - - // TODO: Fix error code - if (error) - *error = g_error_new(g_quark_from_static_string("org.bluez.Error.Rejected"), 0, "Passkey doesn't match"); - return FALSE; - } - } else if (self->priv->interactive) { - g_print("Confirm passkey: %u (yes/no)? ", passkey); - gchar yn[4] = {0,}; - errno = 0; - if (scanf("%3s", yn) == EOF && errno) { - g_warning("%s\n", strerror(errno)); - } - if (g_strcmp0(yn, "y") == 0 || g_strcmp0(yn, "yes") == 0) { - return TRUE; - } else { - // TODO: Fix error code - if (error) - *error = g_error_new(g_quark_from_static_string("org.bluez.Error.Rejected"), 0, "Passkey doesn't match"); - return FALSE; - } - } - - return FALSE; // Request rejected -} - -gboolean agent_authorize(Agent *self, const gchar *device, const gchar *uuid, GError **error) -{ - Device *device_obj = g_object_new(DEVICE_TYPE, "DBusObjectPath", device, NULL); - const gchar *pin = find_device_pin(self, device_obj); - - if (self->priv->interactive) - g_print("Device: %s (%s)\n", device_get_alias(device_obj), device_get_address(device_obj)); - - g_object_unref(device_obj); - - if (pin != NULL) { - if (self->priv->interactive) - g_print("Connection to %s authorized\n", uuid2name(uuid)); - - return TRUE; - } else if (self->priv->interactive) { - g_print("Authorize a connection to: %s (yes/no)? ", uuid2name(uuid)); - gchar yn[4] = {0,}; - errno = 0; - if (scanf("%3s", yn) == EOF && errno) { - g_warning("%s\n", strerror(errno)); - } - if (g_strcmp0(yn, "y") == 0 || g_strcmp0(yn, "yes") == 0) { - return TRUE; - } else { - // TODO: Fix error code - if (error) - *error = g_error_new(g_quark_from_static_string("org.bluez.Error.Rejected"), 0, "Connection rejected by user"); - return FALSE; - } - } - - return FALSE; // Request rejected -} - -gboolean agent_confirm_mode_change(Agent *self, const gchar *mode, GError **error) -{ - if (self->priv->interactive) { - g_print("Confirm mode change: %s (yes/no)? ", mode); - gchar yn[4] = {0,}; - errno = 0; - if (scanf("%3s", yn) == EOF && errno) { - g_warning("%s\n", strerror(errno)); - } - if (g_strcmp0(yn, "y") == 0 || g_strcmp0(yn, "yes") == 0) { - return TRUE; - } else { - // TODO: Fix error code - if (error) - *error = g_error_new(g_quark_from_static_string("org.bluez.Error.Rejected"), 0, "Confirmation rejected by user"); - return FALSE; - } - } - - return TRUE; // Request accepted -} - -gboolean agent_cancel(Agent *self, GError **error) -{ - if (self->priv->interactive) - g_print("Request cancelled\n"); - - return TRUE; -} - diff --git a/src/lib/bluez/agent.h b/src/lib/bluez/agent.h deleted file mode 100644 index 10f4944..0000000 --- a/src/lib/bluez/agent.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __AGENT_H -#define __AGENT_H - -#include <glib-object.h> -#include <dbus/dbus-glib.h> - -#include "../marshallers.h" - -#define AGENT_DBUS_PATH "/Agent" - -/* - * Type macros - */ -#define AGENT_TYPE (agent_get_type()) -#define AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGENT_TYPE, Agent)) -#define AGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), AGENT_TYPE)) -#define AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), AGENT_TYPE, AgentClass)) -#define AGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), AGENT_TYPE)) -#define AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), AGENT_TYPE, AgentClass)) - -typedef struct _Agent Agent; -typedef struct _AgentClass AgentClass; -typedef struct _AgentPrivate AgentPrivate; - -struct _Agent { - GObject parent_instance; - - /*< private >*/ - AgentPrivate *priv; -}; - -struct _AgentClass { - GObjectClass parent_class; -}; - -/* used by AGENT_TYPE */ -GType agent_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -gboolean agent_release(Agent *self, GError **error); -gboolean agent_request_pin_code(Agent *self, const gchar *device, gchar **ret, GError **error); -gboolean agent_request_passkey(Agent *self, const gchar *device, guint *ret, GError **error); -gboolean agent_display_passkey(Agent *self, const gchar *device, guint passkey, guint8 entered, GError **error); -gboolean agent_request_confirmation(Agent *self, const gchar *device, guint passkey, GError **error); -gboolean agent_authorize(Agent *self, const gchar *device, const gchar *uuid, GError **error); -gboolean agent_confirm_mode_change(Agent *self, const gchar *mode, GError **error); -gboolean agent_cancel(Agent *self, GError **error); - -/* Glue code */ -static const DBusGMethodInfo dbus_glib_agent_methods[] = { - { (GCallback) agent_release, g_cclosure_bt_marshal_BOOLEAN__POINTER, 0}, - { (GCallback) agent_request_pin_code, g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER_POINTER, 27}, - { (GCallback) agent_request_passkey, g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER_POINTER, 85}, - { (GCallback) agent_display_passkey, g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER, 143}, - { (GCallback) agent_request_confirmation, g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT_POINTER, 212}, - { (GCallback) agent_authorize, g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_POINTER, 274}, - { (GCallback) agent_confirm_mode_change, g_cclosure_bt_marshal_BOOLEAN__STRING_POINTER, 323}, - { (GCallback) agent_cancel, g_cclosure_bt_marshal_BOOLEAN__POINTER, 369}, -}; - -static const DBusGObjectInfo dbus_glib_agent_object_info = { - 0, - dbus_glib_agent_methods, - 8, - "org.bluez.Agent\0Release\0S\0\0org.bluez.Agent\0RequestPinCode\0S\0device\0I\0o\0arg1\0O\0F\0N\0s\0\0org.bluez.Agent\0RequestPasskey\0S\0device\0I\0o\0arg1\0O\0F\0N\0u\0\0org.bluez.Agent\0DisplayPasskey\0S\0device\0I\0o\0passkey\0I\0u\0entered\0I\0y\0\0org.bluez.Agent\0RequestConfirmation\0S\0device\0I\0o\0passkey\0I\0u\0\0org.bluez.Agent\0Authorize\0S\0device\0I\0o\0uuid\0I\0s\0\0org.bluez.Agent\0ConfirmModeChange\0S\0mode\0I\0s\0\0org.bluez.Agent\0Cancel\0S\0\0\0", - "\0", - "\0" -}; - -#endif /* __AGENT_H */ - diff --git a/src/lib/bluez/agent_manager.c b/src/lib/bluez/agent_manager.c new file mode 100644 index 0000000..9d501ff --- /dev/null +++ b/src/lib/bluez/agent_manager.c @@ -0,0 +1,161 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "agent_manager.h" + +#define AGENT_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), AGENT_MANAGER_TYPE, AgentManagerPrivate)) + +struct _AgentManagerPrivate { + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(AgentManager, agent_manager, G_TYPE_OBJECT); + +enum { + PROP_0, +}; + +static void _agent_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _agent_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _agent_manager_create_gdbus_proxy(AgentManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void agent_manager_dispose(GObject *gobject) +{ + AgentManager *self = AGENT_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Chain up to the parent class */ + G_OBJECT_CLASS(agent_manager_parent_class)->dispose(gobject); +} + +static void agent_manager_finalize (GObject *gobject) +{ + AgentManager *self = AGENT_MANAGER(gobject); + G_OBJECT_CLASS(agent_manager_parent_class)->finalize(gobject); +} + +static void agent_manager_class_init(AgentManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = agent_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _agent_manager_get_property; + gobject_class->set_property = _agent_manager_set_property; + if (pspec) + g_param_spec_unref(pspec); +} + +static void agent_manager_init(AgentManager *self) +{ + self->priv = agent_manager_get_instance_private (self); + self->priv->proxy = NULL; + g_assert(system_conn != NULL); + GError *error = NULL; + _agent_manager_create_gdbus_proxy(self, AGENT_MANAGER_DBUS_SERVICE, AGENT_MANAGER_DBUS_PATH, &error); + g_assert(error == NULL); +} + +static void _agent_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + AgentManager *self = AGENT_MANAGER(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _agent_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + AgentManager *self = AGENT_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +AgentManager *agent_manager_new() +{ + return g_object_new(AGENT_MANAGER_TYPE, NULL); +} + +/* Private DBus proxy creation */ +static void _agent_manager_create_gdbus_proxy(AgentManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(AGENT_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, AGENT_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* void RegisterAgent(object agent, string capability) */ +void agent_manager_register_agent(AgentManager *self, const gchar *agent, const gchar *capability, GError **error) +{ + g_assert(AGENT_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RegisterAgent", g_variant_new ("(os)", agent, capability), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void RequestDefaultAgent(object agent) */ +void agent_manager_request_default_agent(AgentManager *self, const gchar *agent, GError **error) +{ + g_assert(AGENT_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RequestDefaultAgent", g_variant_new ("(o)", agent), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UnregisterAgent(object agent) */ +void agent_manager_unregister_agent(AgentManager *self, const gchar *agent, GError **error) +{ + g_assert(AGENT_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UnregisterAgent", g_variant_new ("(o)", agent), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/agent_manager.h b/src/lib/bluez/agent_manager.h new file mode 100644 index 0000000..42f4f5e --- /dev/null +++ b/src/lib/bluez/agent_manager.h @@ -0,0 +1,82 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __AGENT_MANAGER_H +#define __AGENT_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define AGENT_MANAGER_DBUS_SERVICE "org.bluez" +#define AGENT_MANAGER_DBUS_INTERFACE "org.bluez.AgentManager1" +#define AGENT_MANAGER_DBUS_PATH "/org/bluez" + +/* + * Type macros + */ +#define AGENT_MANAGER_TYPE (agent_manager_get_type()) +#define AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGENT_MANAGER_TYPE, AgentManager)) +#define AGENT_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), AGENT_MANAGER_TYPE)) +#define AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), AGENT_MANAGER_TYPE, AgentManagerClass)) +#define AGENT_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), AGENT_MANAGER_TYPE)) +#define AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), AGENT_MANAGER_TYPE, AgentManagerClass)) + +typedef struct _AgentManager AgentManager; +typedef struct _AgentManagerClass AgentManagerClass; +typedef struct _AgentManagerPrivate AgentManagerPrivate; + +struct _AgentManager { + GObject parent_instance; + + /*< private >*/ + AgentManagerPrivate *priv; +}; + +struct _AgentManagerClass { + GObjectClass parent_class; +}; + +/* used by AGENT_MANAGER_TYPE */ +GType agent_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +AgentManager *agent_manager_new(); + +/* + * Method definitions + */ +void agent_manager_register_agent(AgentManager *self, const gchar *agent, const gchar *capability, GError **error); +void agent_manager_request_default_agent(AgentManager *self, const gchar *agent, GError **error); +void agent_manager_unregister_agent(AgentManager *self, const gchar *agent, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __AGENT_MANAGER_H */ + diff --git a/src/lib/bluez/alert.c b/src/lib/bluez/alert.c new file mode 100644 index 0000000..43f4e5e --- /dev/null +++ b/src/lib/bluez/alert.c @@ -0,0 +1,161 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "alert.h" + +#define ALERT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ALERT_TYPE, AlertPrivate)) + +struct _AlertPrivate { + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(Alert, alert, G_TYPE_OBJECT); + +enum { + PROP_0, +}; + +static void _alert_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _alert_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _alert_create_gdbus_proxy(Alert *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void alert_dispose(GObject *gobject) +{ + Alert *self = ALERT(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Chain up to the parent class */ + G_OBJECT_CLASS(alert_parent_class)->dispose(gobject); +} + +static void alert_finalize (GObject *gobject) +{ + Alert *self = ALERT(gobject); + G_OBJECT_CLASS(alert_parent_class)->finalize(gobject); +} + +static void alert_class_init(AlertClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = alert_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _alert_get_property; + gobject_class->set_property = _alert_set_property; + if (pspec) + g_param_spec_unref(pspec); +} + +static void alert_init(Alert *self) +{ + self->priv = alert_get_instance_private (self); + self->priv->proxy = NULL; + g_assert(system_conn != NULL); + GError *error = NULL; + _alert_create_gdbus_proxy(self, ALERT_DBUS_SERVICE, ALERT_DBUS_PATH, &error); + g_assert(error == NULL); +} + +static void _alert_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Alert *self = ALERT(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _alert_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Alert *self = ALERT(object); + GError *error = NULL; + + switch (property_id) { + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +Alert *alert_new() +{ + return g_object_new(ALERT_TYPE, NULL); +} + +/* Private DBus proxy creation */ +static void _alert_create_gdbus_proxy(Alert *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(ALERT_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, ALERT_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* void NewAlert(string category, uint16 count, string description) */ +void alert_new_alert(Alert *self, const gchar *category, const guint16 count, const gchar *description, GError **error) +{ + g_assert(ALERT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "NewAlert", g_variant_new ("(sqs)", category, count, description), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void RegisterAlert(string category, object agent) */ +void alert_register_alert(Alert *self, const gchar *category, const gchar *agent, GError **error) +{ + g_assert(ALERT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RegisterAlert", g_variant_new ("(so)", category, agent), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UnreadAlert(string category, uint16 count) */ +void alert_unread_alert(Alert *self, const gchar *category, const guint16 count, GError **error) +{ + g_assert(ALERT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UnreadAlert", g_variant_new ("(sq)", category, count), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/alert.h b/src/lib/bluez/alert.h new file mode 100644 index 0000000..28508dd --- /dev/null +++ b/src/lib/bluez/alert.h @@ -0,0 +1,82 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ALERT_H +#define __ALERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define ALERT_DBUS_SERVICE "org.bluez" +#define ALERT_DBUS_INTERFACE "org.bluez.Alert1" +#define ALERT_DBUS_PATH "/org/bluez" + +/* + * Type macros + */ +#define ALERT_TYPE (alert_get_type()) +#define ALERT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), ALERT_TYPE, Alert)) +#define ALERT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), ALERT_TYPE)) +#define ALERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), ALERT_TYPE, AlertClass)) +#define ALERT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), ALERT_TYPE)) +#define ALERT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), ALERT_TYPE, AlertClass)) + +typedef struct _Alert Alert; +typedef struct _AlertClass AlertClass; +typedef struct _AlertPrivate AlertPrivate; + +struct _Alert { + GObject parent_instance; + + /*< private >*/ + AlertPrivate *priv; +}; + +struct _AlertClass { + GObjectClass parent_class; +}; + +/* used by ALERT_TYPE */ +GType alert_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +Alert *alert_new(); + +/* + * Method definitions + */ +void alert_new_alert(Alert *self, const gchar *category, const guint16 count, const gchar *description, GError **error); +void alert_register_alert(Alert *self, const gchar *category, const gchar *agent, GError **error); +void alert_unread_alert(Alert *self, const gchar *category, const guint16 count, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __ALERT_H */ + diff --git a/src/lib/bluez/alert_agent.c b/src/lib/bluez/alert_agent.c new file mode 100644 index 0000000..ceb3cab --- /dev/null +++ b/src/lib/bluez/alert_agent.c @@ -0,0 +1,183 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "alert_agent.h" + +#define ALERT_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ALERT_AGENT_TYPE, AlertAgentPrivate)) + +struct _AlertAgentPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(AlertAgent, alert_agent, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _alert_agent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _alert_agent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _alert_agent_create_gdbus_proxy(AlertAgent *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void alert_agent_dispose(GObject *gobject) +{ + AlertAgent *self = ALERT_AGENT(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(alert_agent_parent_class)->dispose(gobject); +} + +static void alert_agent_finalize (GObject *gobject) +{ + AlertAgent *self = ALERT_AGENT(gobject); + G_OBJECT_CLASS(alert_agent_parent_class)->finalize(gobject); +} + +static void alert_agent_class_init(AlertAgentClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = alert_agent_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _alert_agent_get_property; + gobject_class->set_property = _alert_agent_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "AlertAgent D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void alert_agent_init(AlertAgent *self) +{ + self->priv = alert_agent_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _alert_agent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + AlertAgent *self = ALERT_AGENT(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, alert_agent_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _alert_agent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + AlertAgent *self = ALERT_AGENT(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _alert_agent_create_gdbus_proxy(self, ALERT_AGENT_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +AlertAgent *alert_agent_new(const gchar *dbus_object_path) +{ + return g_object_new(ALERT_AGENT_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _alert_agent_create_gdbus_proxy(AlertAgent *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(ALERT_AGENT_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, ALERT_AGENT_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *alert_agent_get_dbus_object_path(AlertAgent *self) +{ + g_assert(ALERT_AGENT_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void MuteOnce() */ +void alert_agent_mute_once(AlertAgent *self, GError **error) +{ + g_assert(ALERT_AGENT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "MuteOnce", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Release() */ +void alert_agent_release(AlertAgent *self, GError **error) +{ + g_assert(ALERT_AGENT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Release", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void SetRinger(string mode) */ +void alert_agent_set_ringer(AlertAgent *self, const gchar *mode, GError **error) +{ + g_assert(ALERT_AGENT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "SetRinger", g_variant_new ("(s)", mode), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/alert_agent.h b/src/lib/bluez/alert_agent.h new file mode 100644 index 0000000..ebba39d --- /dev/null +++ b/src/lib/bluez/alert_agent.h @@ -0,0 +1,83 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ALERT_AGENT_H +#define __ALERT_AGENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define ALERT_AGENT_DBUS_SERVICE "org.bluez" +#define ALERT_AGENT_DBUS_INTERFACE "org.bluez.AlertAgent1" + +/* + * Type macros + */ +#define ALERT_AGENT_TYPE (alert_agent_get_type()) +#define ALERT_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), ALERT_AGENT_TYPE, AlertAgent)) +#define ALERT_AGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), ALERT_AGENT_TYPE)) +#define ALERT_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), ALERT_AGENT_TYPE, AlertAgentClass)) +#define ALERT_AGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), ALERT_AGENT_TYPE)) +#define ALERT_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), ALERT_AGENT_TYPE, AlertAgentClass)) + +typedef struct _AlertAgent AlertAgent; +typedef struct _AlertAgentClass AlertAgentClass; +typedef struct _AlertAgentPrivate AlertAgentPrivate; + +struct _AlertAgent { + GObject parent_instance; + + /*< private >*/ + AlertAgentPrivate *priv; +}; + +struct _AlertAgentClass { + GObjectClass parent_class; +}; + +/* used by ALERT_AGENT_TYPE */ +GType alert_agent_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +AlertAgent *alert_agent_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *alert_agent_get_dbus_object_path(AlertAgent *self); + +void alert_agent_mute_once(AlertAgent *self, GError **error); +void alert_agent_release(AlertAgent *self, GError **error); +void alert_agent_set_ringer(AlertAgent *self, const gchar *mode, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __ALERT_AGENT_H */ + diff --git a/src/lib/bluez/audio.c b/src/lib/bluez/audio.c deleted file mode 100644 index 8343bf5..0000000 --- a/src/lib/bluez/audio.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib.h> -#include <dbus/dbus-glib.h> - -#include "../dbus-common.h" -#include "../marshallers.h" - -#include "audio.h" - -#define AUDIO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), AUDIO_TYPE, AudioPrivate)) - -struct _AudioPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gchar *state; -}; - -G_DEFINE_TYPE(Audio, audio, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_STATE /* readonly */ -}; - -static void _audio_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _audio_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -enum { - PROPERTY_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); - -static void audio_dispose(GObject *gobject) -{ - Audio *self = AUDIO(gobject); - - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self); - - /* Properties free */ - g_free(self->priv->state); - - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - - /* Chain up to the parent class */ - G_OBJECT_CLASS(audio_parent_class)->dispose(gobject); -} - -static void audio_class_init(AudioClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = audio_dispose; - - g_type_class_add_private(klass, sizeof(AudioPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _audio_get_property; - gobject_class->set_property = _audio_set_property; - - /* object DBusObjectPath [readwrite, construct only] */ - pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); - - /* string State [readonly] */ - pspec = g_param_spec_string("State", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_STATE, pspec); - - /* Signals registation */ - signals[PROPERTY_CHANGED] = g_signal_new("PropertyChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); -} - -static void audio_init(Audio *self) -{ - self->priv = AUDIO_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(system_conn != NULL); -} - -static void audio_post_init(Audio *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", AUDIO_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", AUDIO_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, AUDIO_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* PropertyChanged(string name, variant value) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self, NULL); - - /* Properties init */ - GHashTable *properties = audio_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* string State [readonly] */ - if (g_hash_table_lookup(properties, "State")) { - self->priv->state = g_value_dup_string(g_hash_table_lookup(properties, "State")); - } else { - self->priv->state = g_strdup("undefined"); - } - - g_hash_table_unref(properties); -} - -static void _audio_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - Audio *self = AUDIO(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, audio_get_dbus_object_path(self)); - break; - - case PROP_STATE: - g_value_set_string(value, audio_get_state(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _audio_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - Audio *self = AUDIO(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - audio_post_init(self, g_value_get_string(value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); -} - -/* Methods */ - -/* void Connect() */ -void audio_connect(Audio *self, GError **error) -{ - g_assert(AUDIO_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Connect", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void Disconnect() */ -void audio_disconnect(Audio *self, GError **error) -{ - g_assert(AUDIO_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* dict GetProperties() */ -GHashTable *audio_get_properties(Audio *self, GError **error) -{ - g_assert(AUDIO_IS(self)); - - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); - - return ret; -} - -/* Properties access methods */ -const gchar *audio_get_dbus_object_path(Audio *self) -{ - g_assert(AUDIO_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - -const gchar *audio_get_state(Audio *self) -{ - g_assert(AUDIO_IS(self)); - - return self->priv->state; -} - -/* Signals handlers */ -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) -{ - Audio *self = AUDIO(data); - - if (g_strcmp0(name, "State") == 0) { - g_free(self->priv->state); - self->priv->state = g_value_dup_string(value); - } - - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); -} - diff --git a/src/lib/bluez/audio.h b/src/lib/bluez/audio.h deleted file mode 100644 index 6d801f2..0000000 --- a/src/lib/bluez/audio.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __AUDIO_H -#define __AUDIO_H - -#include <glib-object.h> - -#define AUDIO_DBUS_INTERFACE "org.bluez.Audio" - -/* - * Type macros - */ -#define AUDIO_TYPE (audio_get_type()) -#define AUDIO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AUDIO_TYPE, Audio)) -#define AUDIO_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), AUDIO_TYPE)) -#define AUDIO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), AUDIO_TYPE, AudioClass)) -#define AUDIO_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), AUDIO_TYPE)) -#define AUDIO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), AUDIO_TYPE, AudioClass)) - -typedef struct _Audio Audio; -typedef struct _AudioClass AudioClass; -typedef struct _AudioPrivate AudioPrivate; - -struct _Audio { - GObject parent_instance; - - /*< private >*/ - AudioPrivate *priv; -}; - -struct _AudioClass { - GObjectClass parent_class; -}; - -/* used by AUDIO_TYPE */ -GType audio_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void audio_connect(Audio *self, GError **error); -void audio_disconnect(Audio *self, GError **error); -GHashTable *audio_get_properties(Audio *self, GError **error); - -const gchar *audio_get_dbus_object_path(Audio *self); -const gchar *audio_get_state(Audio *self); - -#endif /* __AUDIO_H */ - diff --git a/src/lib/bluez/cycling_speed.c b/src/lib/bluez/cycling_speed.c new file mode 100644 index 0000000..d09468a --- /dev/null +++ b/src/lib/bluez/cycling_speed.c @@ -0,0 +1,210 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "cycling_speed.h" + +#define CYCLING_SPEED_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CYCLING_SPEED_TYPE, CyclingSpeedPrivate)) + +struct _CyclingSpeedPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(CyclingSpeed, cycling_speed, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _cycling_speed_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _cycling_speed_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _cycling_speed_create_gdbus_proxy(CyclingSpeed *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void cycling_speed_dispose(GObject *gobject) +{ + CyclingSpeed *self = CYCLING_SPEED(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(cycling_speed_parent_class)->dispose(gobject); +} + +static void cycling_speed_finalize (GObject *gobject) +{ + CyclingSpeed *self = CYCLING_SPEED(gobject); + G_OBJECT_CLASS(cycling_speed_parent_class)->finalize(gobject); +} + +static void cycling_speed_class_init(CyclingSpeedClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = cycling_speed_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _cycling_speed_get_property; + gobject_class->set_property = _cycling_speed_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "CyclingSpeed D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void cycling_speed_init(CyclingSpeed *self) +{ + self->priv = cycling_speed_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _cycling_speed_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + CyclingSpeed *self = CYCLING_SPEED(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, cycling_speed_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _cycling_speed_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + CyclingSpeed *self = CYCLING_SPEED(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _cycling_speed_create_gdbus_proxy(self, CYCLING_SPEED_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +CyclingSpeed *cycling_speed_new(const gchar *dbus_object_path) +{ + return g_object_new(CYCLING_SPEED_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _cycling_speed_create_gdbus_proxy(CyclingSpeed *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(CYCLING_SPEED_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, CYCLING_SPEED_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *cycling_speed_get_dbus_object_path(CyclingSpeed *self) +{ + g_assert(CYCLING_SPEED_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + + + +/* Properties access methods */ +GVariant *cycling_speed_get_properties(CyclingSpeed *self, GError **error) +{ + g_assert(CYCLING_SPEED_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, CYCLING_SPEED_DBUS_INTERFACE, error); +} + +void cycling_speed_set_property(CyclingSpeed *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(CYCLING_SPEED_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, CYCLING_SPEED_DBUS_INTERFACE, name, value, error); +} + +gboolean cycling_speed_get_multiple_locations_supported(CyclingSpeed *self, GError **error) +{ + g_assert(CYCLING_SPEED_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, CYCLING_SPEED_DBUS_INTERFACE, "MultipleLocationsSupported", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +gboolean cycling_speed_get_wheel_revolution_data_supported(CyclingSpeed *self, GError **error) +{ + g_assert(CYCLING_SPEED_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, CYCLING_SPEED_DBUS_INTERFACE, "WheelRevolutionDataSupported", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/cycling_speed.h b/src/lib/bluez/cycling_speed.h new file mode 100644 index 0000000..f60c16c --- /dev/null +++ b/src/lib/bluez/cycling_speed.h @@ -0,0 +1,85 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CYCLING_SPEED_H +#define __CYCLING_SPEED_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define CYCLING_SPEED_DBUS_SERVICE "org.bluez" +#define CYCLING_SPEED_DBUS_INTERFACE "org.bluez.CyclingSpeed1" + +/* + * Type macros + */ +#define CYCLING_SPEED_TYPE (cycling_speed_get_type()) +#define CYCLING_SPEED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CYCLING_SPEED_TYPE, CyclingSpeed)) +#define CYCLING_SPEED_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CYCLING_SPEED_TYPE)) +#define CYCLING_SPEED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CYCLING_SPEED_TYPE, CyclingSpeedClass)) +#define CYCLING_SPEED_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CYCLING_SPEED_TYPE)) +#define CYCLING_SPEED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CYCLING_SPEED_TYPE, CyclingSpeedClass)) + +typedef struct _CyclingSpeed CyclingSpeed; +typedef struct _CyclingSpeedClass CyclingSpeedClass; +typedef struct _CyclingSpeedPrivate CyclingSpeedPrivate; + +struct _CyclingSpeed { + GObject parent_instance; + + /*< private >*/ + CyclingSpeedPrivate *priv; +}; + +struct _CyclingSpeedClass { + GObjectClass parent_class; +}; + +/* used by CYCLING_SPEED_TYPE */ +GType cycling_speed_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +CyclingSpeed *cycling_speed_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *cycling_speed_get_dbus_object_path(CyclingSpeed *self); + +GVariant *cycling_speed_get_properties(CyclingSpeed *self, GError **error); +void cycling_speed_set_property(CyclingSpeed *self, const gchar *name, const GVariant *value, GError **error); + +gboolean cycling_speed_get_multiple_locations_supported(CyclingSpeed *self, GError **error); +gboolean cycling_speed_get_wheel_revolution_data_supported(CyclingSpeed *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __CYCLING_SPEED_H */ + diff --git a/src/lib/bluez/cycling_speed_manager.c b/src/lib/bluez/cycling_speed_manager.c new file mode 100644 index 0000000..36e9e6a --- /dev/null +++ b/src/lib/bluez/cycling_speed_manager.c @@ -0,0 +1,162 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "cycling_speed_manager.h" + +#define CYCLING_SPEED_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CYCLING_SPEED_MANAGER_TYPE, CyclingSpeedManagerPrivate)) + +struct _CyclingSpeedManagerPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(CyclingSpeedManager, cycling_speed_manager, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _cycling_speed_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _cycling_speed_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _cycling_speed_manager_create_gdbus_proxy(CyclingSpeedManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void cycling_speed_manager_dispose(GObject *gobject) +{ + CyclingSpeedManager *self = CYCLING_SPEED_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(cycling_speed_manager_parent_class)->dispose(gobject); +} + +static void cycling_speed_manager_finalize (GObject *gobject) +{ + CyclingSpeedManager *self = CYCLING_SPEED_MANAGER(gobject); + G_OBJECT_CLASS(cycling_speed_manager_parent_class)->finalize(gobject); +} + +static void cycling_speed_manager_class_init(CyclingSpeedManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = cycling_speed_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _cycling_speed_manager_get_property; + gobject_class->set_property = _cycling_speed_manager_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "CyclingSpeedManager D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void cycling_speed_manager_init(CyclingSpeedManager *self) +{ + self->priv = cycling_speed_manager_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _cycling_speed_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + CyclingSpeedManager *self = CYCLING_SPEED_MANAGER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, cycling_speed_manager_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _cycling_speed_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + CyclingSpeedManager *self = CYCLING_SPEED_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _cycling_speed_manager_create_gdbus_proxy(self, CYCLING_SPEED_MANAGER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +CyclingSpeedManager *cycling_speed_manager_new(const gchar *dbus_object_path) +{ + return g_object_new(CYCLING_SPEED_MANAGER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _cycling_speed_manager_create_gdbus_proxy(CyclingSpeedManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(CYCLING_SPEED_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, CYCLING_SPEED_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *cycling_speed_manager_get_dbus_object_path(CyclingSpeedManager *self) +{ + g_assert(CYCLING_SPEED_MANAGER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + diff --git a/src/lib/bluez/cycling_speed_manager.h b/src/lib/bluez/cycling_speed_manager.h new file mode 100644 index 0000000..dec0455 --- /dev/null +++ b/src/lib/bluez/cycling_speed_manager.h @@ -0,0 +1,75 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CYCLING_SPEED_MANAGER_H +#define __CYCLING_SPEED_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define CYCLING_SPEED_MANAGER_DBUS_SERVICE "org.bluez" +#define CYCLING_SPEED_MANAGER_DBUS_INTERFACE "org.bluez.CyclingSpeedManager1" + +/* + * Type macros + */ +#define CYCLING_SPEED_MANAGER_TYPE (cycling_speed_manager_get_type()) +#define CYCLING_SPEED_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CYCLING_SPEED_MANAGER_TYPE, CyclingSpeedManager)) +#define CYCLING_SPEED_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CYCLING_SPEED_MANAGER_TYPE)) +#define CYCLING_SPEED_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CYCLING_SPEED_MANAGER_TYPE, CyclingSpeedManagerClass)) +#define CYCLING_SPEED_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CYCLING_SPEED_MANAGER_TYPE)) +#define CYCLING_SPEED_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CYCLING_SPEED_MANAGER_TYPE, CyclingSpeedManagerClass)) + +typedef struct _CyclingSpeedManager CyclingSpeedManager; +typedef struct _CyclingSpeedManagerClass CyclingSpeedManagerClass; +typedef struct _CyclingSpeedManagerPrivate CyclingSpeedManagerPrivate; + +struct _CyclingSpeedManager { + GObject parent_instance; + + /*< private >*/ + CyclingSpeedManagerPrivate *priv; +}; + +struct _CyclingSpeedManagerClass { + GObjectClass parent_class; +}; + +/* used by CYCLING_SPEED_MANAGER_TYPE */ +GType cycling_speed_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +CyclingSpeedManager *cycling_speed_manager_new(const gchar *dbus_object_path); +const gchar *cycling_speed_manager_get_dbus_object_path(CyclingSpeedManager *self); + +#ifdef __cplusplus +} +#endif + +#endif /* __CYCLING_SPEED_MANAGER_H */ + diff --git a/src/lib/bluez/device.c b/src/lib/bluez/device.c index 7cc6bc0..0d9f8ec 100644 --- a/src/lib/bluez/device.c +++ b/src/lib/bluez/device.c @@ -24,339 +24,83 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif - -#include <string.h> - +#include <gio/gio.h> #include <glib.h> -#include <dbus/dbus-glib.h> +#include <string.h> #include "../dbus-common.h" -#include "../marshallers.h" +#include "../properties.h" #include "device.h" #define DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), DEVICE_TYPE, DevicePrivate)) struct _DevicePrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gchar *adapter; - gchar *address; - gchar *alias; - gboolean blocked; - guint32 class; - gboolean connected; - gchar *icon; - gboolean legacy_pairing; - gchar *name; - gboolean paired; - GPtrArray *services; - gboolean trusted; - gchar **uuids; + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; }; -G_DEFINE_TYPE(Device, device, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE(Device, device, G_TYPE_OBJECT); enum { PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_ADAPTER, /* readonly */ - PROP_ADDRESS, /* readonly */ - PROP_ALIAS, /* readwrite */ - PROP_BLOCKED, /* readwrite */ - PROP_CLASS, /* readonly */ - PROP_CONNECTED, /* readonly */ - PROP_ICON, /* readonly */ - PROP_LEGACY_PAIRING, /* readonly */ - PROP_NAME, /* readonly */ - PROP_PAIRED, /* readonly */ - PROP_SERVICES, /* readonly */ - PROP_TRUSTED, /* readwrite */ - PROP_UUIDS /* readonly */ + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ }; static void _device_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void _device_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -enum { - DISCONNECT_REQUESTED, - PROPERTY_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void disconnect_requested_handler(DBusGProxy *dbus_g_proxy, gpointer data); -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); +static void _device_create_gdbus_proxy(Device *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); static void device_dispose(GObject *gobject) { Device *self = DEVICE(gobject); - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "DisconnectRequested", G_CALLBACK(disconnect_requested_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self); - - /* Properties free */ - g_free(self->priv->adapter); - g_free(self->priv->address); - g_free(self->priv->alias); - g_free(self->priv->icon); - g_free(self->priv->name); - g_ptr_array_unref(self->priv->services); - g_strfreev(self->priv->uuids); - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); /* Chain up to the parent class */ G_OBJECT_CLASS(device_parent_class)->dispose(gobject); } +static void device_finalize (GObject *gobject) +{ + Device *self = DEVICE(gobject); + G_OBJECT_CLASS(device_parent_class)->finalize(gobject); +} + static void device_class_init(DeviceClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->dispose = device_dispose; - g_type_class_add_private(klass, sizeof(DevicePrivate)); - /* Properties registration */ - GParamSpec *pspec; + GParamSpec *pspec = NULL; gobject_class->get_property = _device_get_property; gobject_class->set_property = _device_set_property; - + /* object DBusObjectPath [readwrite, construct only] */ - pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Device D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); - - /* object Adapter [readonly] */ - pspec = g_param_spec_string("Adapter", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_ADAPTER, pspec); - - /* string Address [readonly] */ - pspec = g_param_spec_string("Address", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_ADDRESS, pspec); - - /* string Alias [readwrite] */ - pspec = g_param_spec_string("Alias", NULL, NULL, NULL, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_ALIAS, pspec); - - /* boolean Blocked [readwrite] */ - pspec = g_param_spec_boolean("Blocked", NULL, NULL, FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_BLOCKED, pspec); - - /* uint32 Class [readonly] */ - pspec = g_param_spec_uint("Class", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_CLASS, pspec); - - /* boolean Connected [readonly] */ - pspec = g_param_spec_boolean("Connected", NULL, NULL, FALSE, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_CONNECTED, pspec); - - /* string Icon [readonly] */ - pspec = g_param_spec_string("Icon", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_ICON, pspec); - - /* boolean LegacyPairing [readonly] */ - pspec = g_param_spec_boolean("LegacyPairing", NULL, NULL, FALSE, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_LEGACY_PAIRING, pspec); - - /* string Name [readonly] */ - pspec = g_param_spec_string("Name", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_NAME, pspec); - - /* boolean Paired [readonly] */ - pspec = g_param_spec_boolean("Paired", NULL, NULL, FALSE, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_PAIRED, pspec); - - /* array{object} Services [readonly] */ - pspec = g_param_spec_boxed("Services", NULL, NULL, G_TYPE_PTR_ARRAY, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_SERVICES, pspec); - - /* boolean Trusted [readwrite] */ - pspec = g_param_spec_boolean("Trusted", NULL, NULL, FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_TRUSTED, pspec); - - /* array{string} UUIDs [readonly] */ - pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_STRV, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_UUIDS, pspec); - - /* Signals registation */ - signals[DISCONNECT_REQUESTED] = g_signal_new("DisconnectRequested", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[PROPERTY_CHANGED] = g_signal_new("PropertyChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); + if (pspec) + g_param_spec_unref(pspec); } static void device_init(Device *self) { - self->priv = DEVICE_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - + self->priv = device_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; g_assert(system_conn != NULL); } -static void device_post_init(Device *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", DEVICE_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", DEVICE_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, DEVICE_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* DisconnectRequested() */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DisconnectRequested", G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DisconnectRequested", G_CALLBACK(disconnect_requested_handler), self, NULL); - - /* PropertyChanged(string name, variant value) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self, NULL); - - /* Properties init */ - GHashTable *properties = device_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* object Adapter [readonly] */ - if (g_hash_table_lookup(properties, "Adapter")) { - self->priv->adapter = (gchar *) g_value_dup_boxed(g_hash_table_lookup(properties, "Adapter")); - } else { - self->priv->adapter = g_strdup("undefined"); - } - - /* string Address [readonly] */ - if (g_hash_table_lookup(properties, "Address")) { - self->priv->address = g_value_dup_string(g_hash_table_lookup(properties, "Address")); - } else { - self->priv->address = g_strdup("undefined"); - } - - /* string Alias [readwrite] */ - if (g_hash_table_lookup(properties, "Alias")) { - self->priv->alias = g_value_dup_string(g_hash_table_lookup(properties, "Alias")); - } else { - self->priv->alias = g_strdup("undefined"); - } - - /* boolean Blocked [readwrite] */ - if (g_hash_table_lookup(properties, "Blocked")) { - self->priv->blocked = g_value_get_boolean(g_hash_table_lookup(properties, "Blocked")); - } else { - self->priv->blocked = FALSE; - } - - /* uint32 Class [readonly] */ - if (g_hash_table_lookup(properties, "Class")) { - self->priv->class = g_value_get_uint(g_hash_table_lookup(properties, "Class")); - } else { - self->priv->class = 0; - } - - /* boolean Connected [readonly] */ - if (g_hash_table_lookup(properties, "Connected")) { - self->priv->connected = g_value_get_boolean(g_hash_table_lookup(properties, "Connected")); - } else { - self->priv->connected = FALSE; - } - - /* string Icon [readonly] */ - if (g_hash_table_lookup(properties, "Icon")) { - self->priv->icon = g_value_dup_string(g_hash_table_lookup(properties, "Icon")); - } else { - self->priv->icon = g_strdup("undefined"); - } - - /* boolean LegacyPairing [readonly] */ - if (g_hash_table_lookup(properties, "LegacyPairing")) { - self->priv->legacy_pairing = g_value_get_boolean(g_hash_table_lookup(properties, "LegacyPairing")); - } else { - self->priv->legacy_pairing = FALSE; - } - - /* string Name [readonly] */ - if (g_hash_table_lookup(properties, "Name")) { - self->priv->name = g_value_dup_string(g_hash_table_lookup(properties, "Name")); - } else { - self->priv->name = g_strdup("undefined"); - } - - /* boolean Paired [readonly] */ - if (g_hash_table_lookup(properties, "Paired")) { - self->priv->paired = g_value_get_boolean(g_hash_table_lookup(properties, "Paired")); - } else { - self->priv->paired = FALSE; - } - - /* array{object} Services [readonly] */ - if (g_hash_table_lookup(properties, "Services")) { - self->priv->services = g_value_dup_boxed(g_hash_table_lookup(properties, "Services")); - } else { - self->priv->services = g_ptr_array_new(); - } - - /* boolean Trusted [readwrite] */ - if (g_hash_table_lookup(properties, "Trusted")) { - self->priv->trusted = g_value_get_boolean(g_hash_table_lookup(properties, "Trusted")); - } else { - self->priv->trusted = FALSE; - } - - /* array{string} UUIDs [readonly] */ - if (g_hash_table_lookup(properties, "UUIDs")) { - self->priv->uuids = (gchar **) g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs")); - } else { - self->priv->uuids = g_new0(char *, 1); - self->priv->uuids[0] = NULL; - } - - g_hash_table_unref(properties); -} - static void _device_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { Device *self = DEVICE(object); @@ -366,58 +110,6 @@ static void _device_get_property(GObject *object, guint property_id, GValue *val g_value_set_string(value, device_get_dbus_object_path(self)); break; - case PROP_ADAPTER: - g_value_set_string(value, device_get_adapter(self)); - break; - - case PROP_ADDRESS: - g_value_set_string(value, device_get_address(self)); - break; - - case PROP_ALIAS: - g_value_set_string(value, device_get_alias(self)); - break; - - case PROP_BLOCKED: - g_value_set_boolean(value, device_get_blocked(self)); - break; - - case PROP_CLASS: - g_value_set_uint(value, device_get_class(self)); - break; - - case PROP_CONNECTED: - g_value_set_boolean(value, device_get_connected(self)); - break; - - case PROP_ICON: - g_value_set_string(value, device_get_icon(self)); - break; - - case PROP_LEGACY_PAIRING: - g_value_set_boolean(value, device_get_legacy_pairing(self)); - break; - - case PROP_NAME: - g_value_set_string(value, device_get_name(self)); - break; - - case PROP_PAIRED: - g_value_set_boolean(value, device_get_paired(self)); - break; - - case PROP_SERVICES: - g_value_set_boxed(value, device_get_services(self)); - break; - - case PROP_TRUSTED: - g_value_set_boolean(value, device_get_trusted(self)); - break; - - case PROP_UUIDS: - g_value_set_boxed(value, device_get_uuids(self)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -431,19 +123,8 @@ static void _device_set_property(GObject *object, guint property_id, const GValu switch (property_id) { case PROP_DBUS_OBJECT_PATH: - device_post_init(self, g_value_get_string(value)); - break; - - case PROP_ALIAS: - device_set_property(self, "Alias", value, &error); - break; - - case PROP_BLOCKED: - device_set_property(self, "Blocked", value, &error); - break; - - case PROP_TRUSTED: - device_set_property(self, "Trusted", value, &error); + self->priv->object_path = g_value_dup_string(value); + _device_create_gdbus_proxy(self, DEVICE_DBUS_SERVICE, self->priv->object_path, &error); break; default: @@ -451,260 +132,320 @@ static void _device_set_property(GObject *object, guint property_id, const GValu break; } - if (error != NULL) { + if (error != NULL) g_critical("%s", error->message); - } + g_assert(error == NULL); } -/* Methods */ +/* Constructor */ +Device *device_new(const gchar *dbus_object_path) +{ + return g_object_new(DEVICE_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} -/* void CancelDiscovery() */ -void device_cancel_discovery(Device *self, GError **error) +/* Private DBus proxy creation */ +static void _device_create_gdbus_proxy(Device *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) { g_assert(DEVICE_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, DEVICE_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "CancelDiscovery", error, G_TYPE_INVALID, G_TYPE_INVALID); + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); } -/* void Disconnect() */ -void device_disconnect(Device *self, GError **error) +/* Methods */ + +/* Get DBus object path */ +const gchar *device_get_dbus_object_path(Device *self) { g_assert(DEVICE_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); } -/* dict{u,s} DiscoverServices(string pattern) */ -GHashTable *device_discover_services(Device *self, const gchar *pattern, GError **error) +/* void CancelPairing() */ +void device_cancel_pairing(Device *self, GError **error) { g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "CancelPairing", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "DiscoverServices", error, G_TYPE_STRING, pattern, G_TYPE_INVALID, DBUS_TYPE_G_UINT_STRING_HASHTABLE, &ret, G_TYPE_INVALID); +/* void Connect() */ +void device_connect(Device *self, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Connect", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} - return ret; +/* void ConnectProfile(string uuid) */ +void device_connect_profile(Device *self, const gchar *uuid, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "ConnectProfile", g_variant_new ("(s)", uuid), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } -/* dict GetProperties() */ -GHashTable *device_get_properties(Device *self, GError **error) +/* void Disconnect() */ +void device_disconnect(Device *self, GError **error) { g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Disconnect", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); +/* void DisconnectProfile(string uuid) */ +void device_disconnect_profile(Device *self, const gchar *uuid, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "DisconnectProfile", g_variant_new ("(s)", uuid), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} - return ret; +/* void Pair() */ +void device_pair(Device *self, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Pair", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } -/* void SetProperty(string name, variant value) */ -void device_set_property(Device *self, const gchar *name, const GValue *value, GError **error) +/* asynchronous call to void Pair() */ +void device_pair_async(Device *self, GAsyncReadyCallback callback, gpointer user_data) { g_assert(DEVICE_IS(self)); + g_dbus_proxy_call (self->priv->proxy, + "Pair", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + callback, + user_data); +} - dbus_g_proxy_call(self->priv->dbus_g_proxy, "SetProperty", error, G_TYPE_STRING, name, G_TYPE_VALUE, value, G_TYPE_INVALID, G_TYPE_INVALID); +/* finish asynchronous call to void Pair() */ +void device_pair_finish(Device *self, GAsyncResult *res, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_dbus_proxy_call_finish (self->priv->proxy, + res, + error); + } /* Properties access methods */ -const gchar *device_get_dbus_object_path(Device *self) +GVariant *device_get_properties(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, DEVICE_DBUS_INTERFACE, error); } -const gchar *device_get_adapter(Device *self) +void device_set_property(Device *self, const gchar *name, const GVariant *value, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->adapter; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, DEVICE_DBUS_INTERFACE, name, value, error); } -const gchar *device_get_address(Device *self) +const gchar *device_get_adapter(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->address; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Adapter", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const gchar *device_get_alias(Device *self) +const gchar *device_get_address(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->alias; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Address", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -void device_set_alias(Device *self, const gchar *value) +const gchar *device_get_alias(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_STRING); - g_value_set_string(&t, value); - device_set_property(self, "Alias", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Alias", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const gboolean device_get_blocked(Device *self) +void device_set_alias(Device *self, const gchar *value, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->blocked; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, DEVICE_DBUS_INTERFACE, "Alias", g_variant_new_string(value), error); } -void device_set_blocked(Device *self, const gboolean value) +guint16 device_get_appearance(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_BOOLEAN); - g_value_set_boolean(&t, value); - device_set_property(self, "Blocked", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Appearance", error); + if(prop == NULL) + return 0; + guint16 ret = g_variant_get_uint16(prop); + g_variant_unref(prop); + return ret; } -const guint32 device_get_class(Device *self) +gboolean device_get_blocked(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->class; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Blocked", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -const gboolean device_get_connected(Device *self) +void device_set_blocked(Device *self, const gboolean value, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->connected; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, DEVICE_DBUS_INTERFACE, "Blocked", g_variant_new_boolean(value), error); } -const gchar *device_get_icon(Device *self) +guint32 device_get_class(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->icon; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Class", error); + if(prop == NULL) + return 0; + guint32 ret = g_variant_get_uint32(prop); + g_variant_unref(prop); + return ret; } -const gboolean device_get_legacy_pairing(Device *self) +gboolean device_get_connected(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->legacy_pairing; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Connected", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -const gchar *device_get_name(Device *self) +const gchar *device_get_icon(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->name; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Icon", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const gboolean device_get_paired(Device *self) +gboolean device_get_legacy_pairing(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->paired; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "LegacyPairing", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -const GPtrArray *device_get_services(Device *self) +const gchar *device_get_modalias(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->services; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Modalias", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -const gboolean device_get_trusted(Device *self) +const gchar *device_get_name(Device *self, GError **error) { g_assert(DEVICE_IS(self)); - - return self->priv->trusted; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Name", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } -void device_set_trusted(Device *self, const gboolean value) +gboolean device_get_paired(Device *self, GError **error) { g_assert(DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Paired", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} - GError *error = NULL; - - GValue t = {0}; - g_value_init(&t, G_TYPE_BOOLEAN); - g_value_set_boolean(&t, value); - device_set_property(self, "Trusted", &t, &error); - g_value_unset(&t); - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); +gint16 device_get_rssi(Device *self, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "RSSI", error); + if(prop == NULL) + return 0; + gint16 ret = g_variant_get_int16(prop); + g_variant_unref(prop); + return ret; } -const gchar **device_get_uuids(Device *self) +gboolean device_get_trusted(Device *self, GError **error) { g_assert(DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "Trusted", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} - return self->priv->uuids; -} - -/* Signals handlers */ -static void disconnect_requested_handler(DBusGProxy *dbus_g_proxy, gpointer data) -{ - Device *self = DEVICE(data); - - g_signal_emit(self, signals[DISCONNECT_REQUESTED], 0); -} - -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) -{ - Device *self = DEVICE(data); - - if (g_strcmp0(name, "Adapter") == 0) { - g_free(self->priv->adapter); - self->priv->adapter = (gchar *) g_value_dup_boxed(value); - } else if (g_strcmp0(name, "Address") == 0) { - g_free(self->priv->address); - self->priv->address = g_value_dup_string(value); - } else if (g_strcmp0(name, "Alias") == 0) { - g_free(self->priv->alias); - self->priv->alias = g_value_dup_string(value); - } else if (g_strcmp0(name, "Blocked") == 0) { - self->priv->blocked = g_value_get_boolean(value); - } else if (g_strcmp0(name, "Class") == 0) { - self->priv->class = g_value_get_uint(value); - } else if (g_strcmp0(name, "Connected") == 0) { - self->priv->connected = g_value_get_boolean(value); - } else if (g_strcmp0(name, "Icon") == 0) { - g_free(self->priv->icon); - self->priv->icon = g_value_dup_string(value); - } else if (g_strcmp0(name, "LegacyPairing") == 0) { - self->priv->legacy_pairing = g_value_get_boolean(value); - } else if (g_strcmp0(name, "Name") == 0) { - g_free(self->priv->name); - self->priv->name = g_value_dup_string(value); - } else if (g_strcmp0(name, "Paired") == 0) { - self->priv->paired = g_value_get_boolean(value); - } else if (g_strcmp0(name, "Services") == 0) { - g_ptr_array_unref(self->priv->services); - self->priv->services = g_value_dup_boxed(value); - } else if (g_strcmp0(name, "Trusted") == 0) { - self->priv->trusted = g_value_get_boolean(value); - } else if (g_strcmp0(name, "UUIDs") == 0) { - g_strfreev(self->priv->uuids); - self->priv->uuids = (gchar **) g_value_dup_boxed(value); - } +void device_set_trusted(Device *self, const gboolean value, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, DEVICE_DBUS_INTERFACE, "Trusted", g_variant_new_boolean(value), error); +} - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); +const gchar **device_get_uuids(Device *self, GError **error) +{ + g_assert(DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, DEVICE_DBUS_INTERFACE, "UUIDs", error); + if(prop == NULL) + return NULL; + const gchar **ret = g_variant_get_strv(prop, NULL); + g_variant_unref(prop); + return ret; } diff --git a/src/lib/bluez/device.h b/src/lib/bluez/device.h index c4f6e2f..20242a2 100644 --- a/src/lib/bluez/device.h +++ b/src/lib/bluez/device.h @@ -24,9 +24,14 @@ #ifndef __DEVICE_H #define __DEVICE_H +#ifdef __cplusplus +extern "C" { +#endif + #include <glib-object.h> -#define DEVICE_DBUS_INTERFACE "org.bluez.Device" +#define DEVICE_DBUS_SERVICE "org.bluez" +#define DEVICE_DBUS_INTERFACE "org.bluez.Device1" /* * Type macros @@ -57,31 +62,49 @@ struct _DeviceClass { GType device_get_type(void) G_GNUC_CONST; /* + * Constructor + */ +Device *device_new(const gchar *dbus_object_path); + +/* * Method definitions */ -void device_cancel_discovery(Device *self, GError **error); +const gchar *device_get_dbus_object_path(Device *self); + +void device_cancel_pairing(Device *self, GError **error); +void device_connect(Device *self, GError **error); +void device_connect_profile(Device *self, const gchar *uuid, GError **error); void device_disconnect(Device *self, GError **error); -GHashTable *device_discover_services(Device *self, const gchar *pattern, GError **error); -GHashTable *device_get_properties(Device *self, GError **error); -void device_set_property(Device *self, const gchar *name, const GValue *value, GError **error); +void device_disconnect_profile(Device *self, const gchar *uuid, GError **error); +void device_pair(Device *self, GError **error); +void device_pair_async(Device *self, GAsyncReadyCallback callback, gpointer user_data); +void device_pair_finish(Device *self, GAsyncResult *res, GError **error); -const gchar *device_get_dbus_object_path(Device *self); -const gchar *device_get_adapter(Device *self); -const gchar *device_get_address(Device *self); -const gchar *device_get_alias(Device *self); -void device_set_alias(Device *self, const gchar *value); -const gboolean device_get_blocked(Device *self); -void device_set_blocked(Device *self, const gboolean value); -const guint32 device_get_class(Device *self); -const gboolean device_get_connected(Device *self); -const gchar *device_get_icon(Device *self); -const gboolean device_get_legacy_pairing(Device *self); -const gchar *device_get_name(Device *self); -const gboolean device_get_paired(Device *self); -const GPtrArray *device_get_services(Device *self); -const gboolean device_get_trusted(Device *self); -void device_set_trusted(Device *self, const gboolean value); -const gchar **device_get_uuids(Device *self); +GVariant *device_get_properties(Device *self, GError **error); +void device_set_property(Device *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *device_get_adapter(Device *self, GError **error); +const gchar *device_get_address(Device *self, GError **error); +const gchar *device_get_alias(Device *self, GError **error); +void device_set_alias(Device *self, const gchar *value, GError **error); +guint16 device_get_appearance(Device *self, GError **error); +gboolean device_get_blocked(Device *self, GError **error); +void device_set_blocked(Device *self, const gboolean value, GError **error); +guint32 device_get_class(Device *self, GError **error); +gboolean device_get_connected(Device *self, GError **error); +const gchar *device_get_icon(Device *self, GError **error); +gboolean device_get_legacy_pairing(Device *self, GError **error); +const gchar *device_get_modalias(Device *self, GError **error); +const gchar *device_get_name(Device *self, GError **error); +gboolean device_get_paired(Device *self, GError **error); +gint16 device_get_rssi(Device *self, GError **error); +gboolean device_get_trusted(Device *self, GError **error); +void device_set_trusted(Device *self, const gboolean value, GError **error); +const gchar **device_get_uuids(Device *self, GError **error); + +#ifdef __cplusplus +} +#endif #endif /* __DEVICE_H */ diff --git a/src/lib/bluez/health_channel.c b/src/lib/bluez/health_channel.c new file mode 100644 index 0000000..2b888fa --- /dev/null +++ b/src/lib/bluez/health_channel.c @@ -0,0 +1,241 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "health_channel.h" + +#define HEALTH_CHANNEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), HEALTH_CHANNEL_TYPE, HealthChannelPrivate)) + +struct _HealthChannelPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(HealthChannel, health_channel, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _health_channel_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _health_channel_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _health_channel_create_gdbus_proxy(HealthChannel *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void health_channel_dispose(GObject *gobject) +{ + HealthChannel *self = HEALTH_CHANNEL(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(health_channel_parent_class)->dispose(gobject); +} + +static void health_channel_finalize (GObject *gobject) +{ + HealthChannel *self = HEALTH_CHANNEL(gobject); + G_OBJECT_CLASS(health_channel_parent_class)->finalize(gobject); +} + +static void health_channel_class_init(HealthChannelClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = health_channel_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _health_channel_get_property; + gobject_class->set_property = _health_channel_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "HealthChannel D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void health_channel_init(HealthChannel *self) +{ + self->priv = health_channel_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _health_channel_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + HealthChannel *self = HEALTH_CHANNEL(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, health_channel_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _health_channel_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + HealthChannel *self = HEALTH_CHANNEL(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _health_channel_create_gdbus_proxy(self, HEALTH_CHANNEL_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +HealthChannel *health_channel_new(const gchar *dbus_object_path) +{ + return g_object_new(HEALTH_CHANNEL_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _health_channel_create_gdbus_proxy(HealthChannel *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, HEALTH_CHANNEL_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *health_channel_get_dbus_object_path(HealthChannel *self) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* fd Acquire() */ +guint32 health_channel_acquire(HealthChannel *self, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + guint32 ret = 0; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "Acquire", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return 0; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_uint32(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +/* void Release() */ +void health_channel_release(HealthChannel *self, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Release", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* Properties access methods */ +GVariant *health_channel_get_properties(HealthChannel *self, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, HEALTH_CHANNEL_DBUS_INTERFACE, error); +} + +void health_channel_set_property(HealthChannel *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, HEALTH_CHANNEL_DBUS_INTERFACE, name, value, error); +} + +const gchar *health_channel_get_application(HealthChannel *self, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, HEALTH_CHANNEL_DBUS_INTERFACE, "Application", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *health_channel_get_device(HealthChannel *self, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, HEALTH_CHANNEL_DBUS_INTERFACE, "Device", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *health_channel_get_channel_type(HealthChannel *self, GError **error) +{ + g_assert(HEALTH_CHANNEL_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, HEALTH_CHANNEL_DBUS_INTERFACE, "Type", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/health_channel.h b/src/lib/bluez/health_channel.h new file mode 100644 index 0000000..4b2a438 --- /dev/null +++ b/src/lib/bluez/health_channel.h @@ -0,0 +1,90 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __HEALTH_CHANNEL_H +#define __HEALTH_CHANNEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define HEALTH_CHANNEL_DBUS_SERVICE "org.bluez" +#define HEALTH_CHANNEL_DBUS_INTERFACE "org.bluez.HealthChannel1" + +/* + * Type macros + */ +#define HEALTH_CHANNEL_TYPE (health_channel_get_type()) +#define HEALTH_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HEALTH_CHANNEL_TYPE, HealthChannel)) +#define HEALTH_CHANNEL_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HEALTH_CHANNEL_TYPE)) +#define HEALTH_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), HEALTH_CHANNEL_TYPE, HealthChannelClass)) +#define HEALTH_CHANNEL_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), HEALTH_CHANNEL_TYPE)) +#define HEALTH_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), HEALTH_CHANNEL_TYPE, HealthChannelClass)) + +typedef struct _HealthChannel HealthChannel; +typedef struct _HealthChannelClass HealthChannelClass; +typedef struct _HealthChannelPrivate HealthChannelPrivate; + +struct _HealthChannel { + GObject parent_instance; + + /*< private >*/ + HealthChannelPrivate *priv; +}; + +struct _HealthChannelClass { + GObjectClass parent_class; +}; + +/* used by HEALTH_CHANNEL_TYPE */ +GType health_channel_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +HealthChannel *health_channel_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *health_channel_get_dbus_object_path(HealthChannel *self); + +guint32 health_channel_acquire(HealthChannel *self, GError **error); +void health_channel_release(HealthChannel *self, GError **error); + +GVariant *health_channel_get_properties(HealthChannel *self, GError **error); +void health_channel_set_property(HealthChannel *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *health_channel_get_application(HealthChannel *self, GError **error); +const gchar *health_channel_get_device(HealthChannel *self, GError **error); +// This has been renamed because 'health_channel_get_type' is already used by GLib +const gchar *health_channel_get_channel_type(HealthChannel *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __HEALTH_CHANNEL_H */ + diff --git a/src/lib/bluez/health_device.c b/src/lib/bluez/health_device.c new file mode 100644 index 0000000..5ff5889 --- /dev/null +++ b/src/lib/bluez/health_device.c @@ -0,0 +1,231 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "health_device.h" + +#define HEALTH_DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), HEALTH_DEVICE_TYPE, HealthDevicePrivate)) + +struct _HealthDevicePrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(HealthDevice, health_device, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _health_device_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _health_device_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _health_device_create_gdbus_proxy(HealthDevice *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void health_device_dispose(GObject *gobject) +{ + HealthDevice *self = HEALTH_DEVICE(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(health_device_parent_class)->dispose(gobject); +} + +static void health_device_finalize (GObject *gobject) +{ + HealthDevice *self = HEALTH_DEVICE(gobject); + G_OBJECT_CLASS(health_device_parent_class)->finalize(gobject); +} + +static void health_device_class_init(HealthDeviceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = health_device_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _health_device_get_property; + gobject_class->set_property = _health_device_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "HealthDevice D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void health_device_init(HealthDevice *self) +{ + self->priv = health_device_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _health_device_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + HealthDevice *self = HEALTH_DEVICE(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, health_device_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _health_device_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + HealthDevice *self = HEALTH_DEVICE(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _health_device_create_gdbus_proxy(self, HEALTH_DEVICE_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +HealthDevice *health_device_new(const gchar *dbus_object_path) +{ + return g_object_new(HEALTH_DEVICE_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _health_device_create_gdbus_proxy(HealthDevice *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, HEALTH_DEVICE_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *health_device_get_dbus_object_path(HealthDevice *self) +{ + g_assert(HEALTH_DEVICE_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* object CreateChannel(object application, string configuration) */ +const gchar *health_device_create_channel(HealthDevice *self, const gchar *application, const gchar *configuration, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + const gchar *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "CreateChannel", g_variant_new ("(os)", application, configuration), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_string(proxy_ret, NULL); + g_variant_unref(proxy_ret); + return ret; +} + +/* void DestroyChannel(object channel) */ +void health_device_destroy_channel(HealthDevice *self, const gchar *channel, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "DestroyChannel", g_variant_new ("(o)", channel), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* boolean Echo() */ +gboolean health_device_echo(HealthDevice *self, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + gboolean ret = FALSE; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "Echo", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return FALSE; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_boolean(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +/* Properties access methods */ +GVariant *health_device_get_properties(HealthDevice *self, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, HEALTH_DEVICE_DBUS_INTERFACE, error); +} + +void health_device_set_property(HealthDevice *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, HEALTH_DEVICE_DBUS_INTERFACE, name, value, error); +} + +const gchar *health_device_get_main_channel(HealthDevice *self, GError **error) +{ + g_assert(HEALTH_DEVICE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, HEALTH_DEVICE_DBUS_INTERFACE, "MainChannel", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/health_device.h b/src/lib/bluez/health_device.h new file mode 100644 index 0000000..6cbd33b --- /dev/null +++ b/src/lib/bluez/health_device.h @@ -0,0 +1,88 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __HEALTH_DEVICE_H +#define __HEALTH_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define HEALTH_DEVICE_DBUS_SERVICE "org.bluez" +#define HEALTH_DEVICE_DBUS_INTERFACE "org.bluez.HealthDevice1" + +/* + * Type macros + */ +#define HEALTH_DEVICE_TYPE (health_device_get_type()) +#define HEALTH_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HEALTH_DEVICE_TYPE, HealthDevice)) +#define HEALTH_DEVICE_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HEALTH_DEVICE_TYPE)) +#define HEALTH_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), HEALTH_DEVICE_TYPE, HealthDeviceClass)) +#define HEALTH_DEVICE_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), HEALTH_DEVICE_TYPE)) +#define HEALTH_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), HEALTH_DEVICE_TYPE, HealthDeviceClass)) + +typedef struct _HealthDevice HealthDevice; +typedef struct _HealthDeviceClass HealthDeviceClass; +typedef struct _HealthDevicePrivate HealthDevicePrivate; + +struct _HealthDevice { + GObject parent_instance; + + /*< private >*/ + HealthDevicePrivate *priv; +}; + +struct _HealthDeviceClass { + GObjectClass parent_class; +}; + +/* used by HEALTH_DEVICE_TYPE */ +GType health_device_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +HealthDevice *health_device_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *health_device_get_dbus_object_path(HealthDevice *self); + +const gchar *health_device_create_channel(HealthDevice *self, const gchar *application, const gchar *configuration, GError **error); +void health_device_destroy_channel(HealthDevice *self, const gchar *channel, GError **error); +gboolean health_device_echo(HealthDevice *self, GError **error); + +GVariant *health_device_get_properties(HealthDevice *self, GError **error); +void health_device_set_property(HealthDevice *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *health_device_get_main_channel(HealthDevice *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __HEALTH_DEVICE_H */ + diff --git a/src/lib/bluez/health_manager.c b/src/lib/bluez/health_manager.c new file mode 100644 index 0000000..1e8f724 --- /dev/null +++ b/src/lib/bluez/health_manager.c @@ -0,0 +1,161 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "health_manager.h" + +#define HEALTH_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), HEALTH_MANAGER_TYPE, HealthManagerPrivate)) + +struct _HealthManagerPrivate { + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(HealthManager, health_manager, G_TYPE_OBJECT); + +enum { + PROP_0, +}; + +static void _health_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _health_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _health_manager_create_gdbus_proxy(HealthManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void health_manager_dispose(GObject *gobject) +{ + HealthManager *self = HEALTH_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Chain up to the parent class */ + G_OBJECT_CLASS(health_manager_parent_class)->dispose(gobject); +} + +static void health_manager_finalize (GObject *gobject) +{ + HealthManager *self = HEALTH_MANAGER(gobject); + G_OBJECT_CLASS(health_manager_parent_class)->finalize(gobject); +} + +static void health_manager_class_init(HealthManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = health_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _health_manager_get_property; + gobject_class->set_property = _health_manager_set_property; + if (pspec) + g_param_spec_unref(pspec); +} + +static void health_manager_init(HealthManager *self) +{ + self->priv = health_manager_get_instance_private (self); + self->priv->proxy = NULL; + g_assert(system_conn != NULL); + GError *error = NULL; + _health_manager_create_gdbus_proxy(self, HEALTH_MANAGER_DBUS_SERVICE, HEALTH_MANAGER_DBUS_PATH, &error); + g_assert(error == NULL); +} + +static void _health_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + HealthManager *self = HEALTH_MANAGER(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _health_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + HealthManager *self = HEALTH_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +HealthManager *health_manager_new() +{ + return g_object_new(HEALTH_MANAGER_TYPE, NULL); +} + +/* Private DBus proxy creation */ +static void _health_manager_create_gdbus_proxy(HealthManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(HEALTH_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, HEALTH_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* object CreateApplication(dict config) */ +const gchar *health_manager_create_application(HealthManager *self, const GVariant *config, GError **error) +{ + g_assert(HEALTH_MANAGER_IS(self)); + const gchar *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "CreateApplication", g_variant_new ("(@a{sv})", config), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_string(proxy_ret, NULL); + g_variant_unref(proxy_ret); + return ret; +} + +/* void DestroyApplication(object application) */ +void health_manager_destroy_application(HealthManager *self, const gchar *application, GError **error) +{ + g_assert(HEALTH_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "DestroyApplication", g_variant_new ("(o)", application), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/health_manager.h b/src/lib/bluez/health_manager.h new file mode 100644 index 0000000..867c707 --- /dev/null +++ b/src/lib/bluez/health_manager.h @@ -0,0 +1,81 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __HEALTH_MANAGER_H +#define __HEALTH_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define HEALTH_MANAGER_DBUS_SERVICE "org.bluez" +#define HEALTH_MANAGER_DBUS_INTERFACE "org.bluez.HealthManager1" +#define HEALTH_MANAGER_DBUS_PATH "/org/bluez/" + +/* + * Type macros + */ +#define HEALTH_MANAGER_TYPE (health_manager_get_type()) +#define HEALTH_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HEALTH_MANAGER_TYPE, HealthManager)) +#define HEALTH_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HEALTH_MANAGER_TYPE)) +#define HEALTH_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), HEALTH_MANAGER_TYPE, HealthManagerClass)) +#define HEALTH_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), HEALTH_MANAGER_TYPE)) +#define HEALTH_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), HEALTH_MANAGER_TYPE, HealthManagerClass)) + +typedef struct _HealthManager HealthManager; +typedef struct _HealthManagerClass HealthManagerClass; +typedef struct _HealthManagerPrivate HealthManagerPrivate; + +struct _HealthManager { + GObject parent_instance; + + /*< private >*/ + HealthManagerPrivate *priv; +}; + +struct _HealthManagerClass { + GObjectClass parent_class; +}; + +/* used by HEALTH_MANAGER_TYPE */ +GType health_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +HealthManager *health_manager_new(); + +/* + * Method definitions + */ +const gchar *health_manager_create_application(HealthManager *self, const GVariant *config, GError **error); +void health_manager_destroy_application(HealthManager *self, const gchar *application, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __HEALTH_MANAGER_H */ + diff --git a/src/lib/bluez/heart_rate.c b/src/lib/bluez/heart_rate.c new file mode 100644 index 0000000..a0bcb0f --- /dev/null +++ b/src/lib/bluez/heart_rate.c @@ -0,0 +1,198 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "heart_rate.h" + +#define HEART_RATE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), HEART_RATE_TYPE, HeartRatePrivate)) + +struct _HeartRatePrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(HeartRate, heart_rate, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _heart_rate_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _heart_rate_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _heart_rate_create_gdbus_proxy(HeartRate *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void heart_rate_dispose(GObject *gobject) +{ + HeartRate *self = HEART_RATE(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(heart_rate_parent_class)->dispose(gobject); +} + +static void heart_rate_finalize (GObject *gobject) +{ + HeartRate *self = HEART_RATE(gobject); + G_OBJECT_CLASS(heart_rate_parent_class)->finalize(gobject); +} + +static void heart_rate_class_init(HeartRateClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = heart_rate_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _heart_rate_get_property; + gobject_class->set_property = _heart_rate_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "HeartRate D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void heart_rate_init(HeartRate *self) +{ + self->priv = heart_rate_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _heart_rate_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + HeartRate *self = HEART_RATE(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, heart_rate_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _heart_rate_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + HeartRate *self = HEART_RATE(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _heart_rate_create_gdbus_proxy(self, HEART_RATE_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +HeartRate *heart_rate_new(const gchar *dbus_object_path) +{ + return g_object_new(HEART_RATE_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _heart_rate_create_gdbus_proxy(HeartRate *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(HEART_RATE_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, HEART_RATE_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *heart_rate_get_dbus_object_path(HeartRate *self) +{ + g_assert(HEART_RATE_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + + + +/* Properties access methods */ +GVariant *heart_rate_get_properties(HeartRate *self, GError **error) +{ + g_assert(HEART_RATE_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, HEART_RATE_DBUS_INTERFACE, error); +} + +void heart_rate_set_property(HeartRate *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(HEART_RATE_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, HEART_RATE_DBUS_INTERFACE, name, value, error); +} + +gboolean heart_rate_get_reset_supported(HeartRate *self, GError **error) +{ + g_assert(HEART_RATE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, HEART_RATE_DBUS_INTERFACE, "ResetSupported", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/heart_rate.h b/src/lib/bluez/heart_rate.h new file mode 100644 index 0000000..1d794ea --- /dev/null +++ b/src/lib/bluez/heart_rate.h @@ -0,0 +1,84 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __HEART_RATE_H +#define __HEART_RATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define HEART_RATE_DBUS_SERVICE "org.bluez" +#define HEART_RATE_DBUS_INTERFACE "org.bluez.HeartRate1" + +/* + * Type macros + */ +#define HEART_RATE_TYPE (heart_rate_get_type()) +#define HEART_RATE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HEART_RATE_TYPE, HeartRate)) +#define HEART_RATE_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HEART_RATE_TYPE)) +#define HEART_RATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), HEART_RATE_TYPE, HeartRateClass)) +#define HEART_RATE_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), HEART_RATE_TYPE)) +#define HEART_RATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), HEART_RATE_TYPE, HeartRateClass)) + +typedef struct _HeartRate HeartRate; +typedef struct _HeartRateClass HeartRateClass; +typedef struct _HeartRatePrivate HeartRatePrivate; + +struct _HeartRate { + GObject parent_instance; + + /*< private >*/ + HeartRatePrivate *priv; +}; + +struct _HeartRateClass { + GObjectClass parent_class; +}; + +/* used by HEART_RATE_TYPE */ +GType heart_rate_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +HeartRate *heart_rate_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *heart_rate_get_dbus_object_path(HeartRate *self); + +GVariant *heart_rate_get_properties(HeartRate *self, GError **error); +void heart_rate_set_property(HeartRate *self, const gchar *name, const GVariant *value, GError **error); + +gboolean heart_rate_get_reset_supported(HeartRate *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __HEART_RATE_H */ + diff --git a/src/lib/bluez/heart_rate_manager.c b/src/lib/bluez/heart_rate_manager.c new file mode 100644 index 0000000..e07bfb3 --- /dev/null +++ b/src/lib/bluez/heart_rate_manager.c @@ -0,0 +1,162 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "heart_rate_manager.h" + +#define HEART_RATE_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), HEART_RATE_MANAGER_TYPE, HeartRateManagerPrivate)) + +struct _HeartRateManagerPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(HeartRateManager, heart_rate_manager, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _heart_rate_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _heart_rate_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _heart_rate_manager_create_gdbus_proxy(HeartRateManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void heart_rate_manager_dispose(GObject *gobject) +{ + HeartRateManager *self = HEART_RATE_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(heart_rate_manager_parent_class)->dispose(gobject); +} + +static void heart_rate_manager_finalize (GObject *gobject) +{ + HeartRateManager *self = HEART_RATE_MANAGER(gobject); + G_OBJECT_CLASS(heart_rate_manager_parent_class)->finalize(gobject); +} + +static void heart_rate_manager_class_init(HeartRateManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = heart_rate_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _heart_rate_manager_get_property; + gobject_class->set_property = _heart_rate_manager_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "HeartRateManager D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void heart_rate_manager_init(HeartRateManager *self) +{ + self->priv = heart_rate_manager_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _heart_rate_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + HeartRateManager *self = HEART_RATE_MANAGER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, heart_rate_manager_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _heart_rate_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + HeartRateManager *self = HEART_RATE_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _heart_rate_manager_create_gdbus_proxy(self, HEART_RATE_MANAGER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +HeartRateManager *heart_rate_manager_new(const gchar *dbus_object_path) +{ + return g_object_new(HEART_RATE_MANAGER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _heart_rate_manager_create_gdbus_proxy(HeartRateManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(HEART_RATE_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, HEART_RATE_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *heart_rate_manager_get_dbus_object_path(HeartRateManager *self) +{ + g_assert(HEART_RATE_MANAGER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + diff --git a/src/lib/bluez/heart_rate_manager.h b/src/lib/bluez/heart_rate_manager.h new file mode 100644 index 0000000..2d5f840 --- /dev/null +++ b/src/lib/bluez/heart_rate_manager.h @@ -0,0 +1,75 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __HEART_RATE_MANAGER_H +#define __HEART_RATE_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define HEART_RATE_MANAGER_DBUS_SERVICE "org.bluez" +#define HEART_RATE_MANAGER_DBUS_INTERFACE "org.bluez.HeartRateManager1" + +/* + * Type macros + */ +#define HEART_RATE_MANAGER_TYPE (heart_rate_manager_get_type()) +#define HEART_RATE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HEART_RATE_MANAGER_TYPE, HeartRateManager)) +#define HEART_RATE_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HEART_RATE_MANAGER_TYPE)) +#define HEART_RATE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), HEART_RATE_MANAGER_TYPE, HeartRateManagerClass)) +#define HEART_RATE_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), HEART_RATE_MANAGER_TYPE)) +#define HEART_RATE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), HEART_RATE_MANAGER_TYPE, HeartRateManagerClass)) + +typedef struct _HeartRateManager HeartRateManager; +typedef struct _HeartRateManagerClass HeartRateManagerClass; +typedef struct _HeartRateManagerPrivate HeartRateManagerPrivate; + +struct _HeartRateManager { + GObject parent_instance; + + /*< private >*/ + HeartRateManagerPrivate *priv; +}; + +struct _HeartRateManagerClass { + GObjectClass parent_class; +}; + +/* used by HEART_RATE_MANAGER_TYPE */ +GType heart_rate_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +HeartRateManager *heart_rate_manager_new(const gchar *dbus_object_path); +const gchar *heart_rate_manager_get_dbus_object_path(HeartRateManager *self); + +#ifdef __cplusplus +} +#endif + +#endif /* __HEART_RATE_MANAGER_H */ + diff --git a/src/lib/bluez/input.c b/src/lib/bluez/input.c deleted file mode 100644 index 0ed19b2..0000000 --- a/src/lib/bluez/input.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib.h> -#include <dbus/dbus-glib.h> - -#include "../dbus-common.h" -#include "../marshallers.h" - -#include "input.h" - -#define INPUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), INPUT_TYPE, InputPrivate)) - -struct _InputPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gboolean connected; -}; - -G_DEFINE_TYPE(Input, input, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_CONNECTED /* readonly */ -}; - -static void _input_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _input_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -enum { - PROPERTY_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); - -static void input_dispose(GObject *gobject) -{ - Input *self = INPUT(gobject); - - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self); - - /* Properties free */ - /* none */ - - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - - /* Chain up to the parent class */ - G_OBJECT_CLASS(input_parent_class)->dispose(gobject); -} - -static void input_class_init(InputClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = input_dispose; - - g_type_class_add_private(klass, sizeof(InputPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _input_get_property; - gobject_class->set_property = _input_set_property; - - /* object DBusObjectPath [readwrite, construct only] */ - pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); - - /* boolean Connected [readonly] */ - pspec = g_param_spec_boolean("Connected", NULL, NULL, FALSE, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_CONNECTED, pspec); - - /* Signals registation */ - signals[PROPERTY_CHANGED] = g_signal_new("PropertyChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); -} - -static void input_init(Input *self) -{ - self->priv = INPUT_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(system_conn != NULL); -} - -static void input_post_init(Input *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", INPUT_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", INPUT_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, INPUT_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* PropertyChanged(string name, variant value) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self, NULL); - - /* Properties init */ - GHashTable *properties = input_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* boolean Connected [readonly] */ - if (g_hash_table_lookup(properties, "Connected")) { - self->priv->connected = g_value_get_boolean(g_hash_table_lookup(properties, "Connected")); - } else { - self->priv->connected = FALSE; - } - - g_hash_table_unref(properties); -} - -static void _input_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - Input *self = INPUT(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, input_get_dbus_object_path(self)); - break; - - case PROP_CONNECTED: - g_value_set_boolean(value, input_get_connected(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _input_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - Input *self = INPUT(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - input_post_init(self, g_value_get_string(value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); -} - -/* Methods */ - -/* void Connect() */ -void input_connect(Input *self, GError **error) -{ - g_assert(INPUT_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Connect", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void Disconnect() */ -void input_disconnect(Input *self, GError **error) -{ - g_assert(INPUT_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* dict GetProperties() */ -GHashTable *input_get_properties(Input *self, GError **error) -{ - g_assert(INPUT_IS(self)); - - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); - - return ret; -} - -/* Properties access methods */ -const gchar *input_get_dbus_object_path(Input *self) -{ - g_assert(INPUT_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - -const gboolean input_get_connected(Input *self) -{ - g_assert(INPUT_IS(self)); - - return self->priv->connected; -} - -/* Signals handlers */ -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) -{ - Input *self = INPUT(data); - - if (g_strcmp0(name, "Connected") == 0) { - self->priv->connected = g_value_get_boolean(value); - } - - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); -} - diff --git a/src/lib/bluez/input.h b/src/lib/bluez/input.h deleted file mode 100644 index 7bf2b86..0000000 --- a/src/lib/bluez/input.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __INPUT_H -#define __INPUT_H - -#include <glib-object.h> - -#define INPUT_DBUS_INTERFACE "org.bluez.Input" - -/* - * Type macros - */ -#define INPUT_TYPE (input_get_type()) -#define INPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), INPUT_TYPE, Input)) -#define INPUT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), INPUT_TYPE)) -#define INPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), INPUT_TYPE, InputClass)) -#define INPUT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), INPUT_TYPE)) -#define INPUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), INPUT_TYPE, InputClass)) - -typedef struct _Input Input; -typedef struct _InputClass InputClass; -typedef struct _InputPrivate InputPrivate; - -struct _Input { - GObject parent_instance; - - /*< private >*/ - InputPrivate *priv; -}; - -struct _InputClass { - GObjectClass parent_class; -}; - -/* used by INPUT_TYPE */ -GType input_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void input_connect(Input *self, GError **error); -void input_disconnect(Input *self, GError **error); -GHashTable *input_get_properties(Input *self, GError **error); - -const gchar *input_get_dbus_object_path(Input *self); -const gboolean input_get_connected(Input *self); - -#endif /* __INPUT_H */ - diff --git a/src/lib/bluez/manager.c b/src/lib/bluez/manager.c deleted file mode 100644 index 53cc597..0000000 --- a/src/lib/bluez/manager.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib.h> -#include <dbus/dbus-glib.h> - -#include "../dbus-common.h" -#include "../marshallers.h" - -#include "manager.h" - -#define MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), MANAGER_TYPE, ManagerPrivate)) - -struct _ManagerPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - GPtrArray *adapters; -}; - -G_DEFINE_TYPE(Manager, manager, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_ADAPTERS /* readonly */ -}; - -static void _manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -enum { - ADAPTER_ADDED, - ADAPTER_REMOVED, - DEFAULT_ADAPTER_CHANGED, - PROPERTY_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void adapter_added_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data); -static void adapter_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data); -static void default_adapter_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data); -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); - -static void manager_dispose(GObject *gobject) -{ - Manager *self = MANAGER(gobject); - - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "AdapterAdded", G_CALLBACK(adapter_added_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "AdapterRemoved", G_CALLBACK(adapter_removed_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "DefaultAdapterChanged", G_CALLBACK(default_adapter_changed_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self); - - /* Properties free */ - g_ptr_array_unref(self->priv->adapters); - - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - - /* Chain up to the parent class */ - G_OBJECT_CLASS(manager_parent_class)->dispose(gobject); -} - -static void manager_class_init(ManagerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = manager_dispose; - - g_type_class_add_private(klass, sizeof(ManagerPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _manager_get_property; - gobject_class->set_property = _manager_set_property; - - /* array{object} Adapters [readonly] */ - pspec = g_param_spec_boxed("Adapters", NULL, NULL, G_TYPE_PTR_ARRAY, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_ADAPTERS, pspec); - - /* Signals registation */ - signals[ADAPTER_ADDED] = g_signal_new("AdapterAdded", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[ADAPTER_REMOVED] = g_signal_new("AdapterRemoved", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[DEFAULT_ADAPTER_CHANGED] = g_signal_new("DefaultAdapterChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - signals[PROPERTY_CHANGED] = g_signal_new("PropertyChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); -} - -static void manager_init(Manager *self) -{ - self->priv = MANAGER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(system_conn != NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", MANAGER_DBUS_PATH, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", MANAGER_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", MANAGER_DBUS_INTERFACE, MANAGER_DBUS_PATH); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", MANAGER_DBUS_PATH, MANAGER_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* AdapterAdded(object adapter) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "AdapterAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "AdapterAdded", G_CALLBACK(adapter_added_handler), self, NULL); - - /* AdapterRemoved(object adapter) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "AdapterRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "AdapterRemoved", G_CALLBACK(adapter_removed_handler), self, NULL); - - /* DefaultAdapterChanged(object adapter) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DefaultAdapterChanged", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DefaultAdapterChanged", G_CALLBACK(default_adapter_changed_handler), self, NULL); - - /* PropertyChanged(string name, variant value) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self, NULL); - - /* Properties init */ - GHashTable *properties = manager_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* array{object} Adapters [readonly] */ - if (g_hash_table_lookup(properties, "Adapters")) { - self->priv->adapters = g_value_dup_boxed(g_hash_table_lookup(properties, "Adapters")); - } else { - self->priv->adapters = g_ptr_array_new(); - } - - g_hash_table_unref(properties); -} - -static void _manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - Manager *self = MANAGER(object); - - switch (property_id) { - case PROP_ADAPTERS: - g_value_set_boxed(value, manager_get_adapters(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - Manager *self = MANAGER(object); - GError *error = NULL; - - switch (property_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); -} - -/* Methods */ - -/* object DefaultAdapter() */ -gchar *manager_default_adapter(Manager *self, GError **error) -{ - g_assert(MANAGER_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "DefaultAdapter", error, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); - - return ret; -} - -/* object FindAdapter(string pattern) */ -gchar *manager_find_adapter(Manager *self, const gchar *pattern, GError **error) -{ - g_assert(MANAGER_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "FindAdapter", error, G_TYPE_STRING, pattern, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); - - return ret; -} - -/* dict GetProperties() */ -GHashTable *manager_get_properties(Manager *self, GError **error) -{ - g_assert(MANAGER_IS(self)); - - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); - - return ret; -} - -/* Properties access methods */ -const GPtrArray *manager_get_adapters(Manager *self) -{ - g_assert(MANAGER_IS(self)); - - return self->priv->adapters; -} - -/* Signals handlers */ -static void adapter_added_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data) -{ - Manager *self = MANAGER(data); - - g_signal_emit(self, signals[ADAPTER_ADDED], 0, adapter); -} - -static void adapter_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data) -{ - Manager *self = MANAGER(data); - - g_signal_emit(self, signals[ADAPTER_REMOVED], 0, adapter); -} - -static void default_adapter_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data) -{ - Manager *self = MANAGER(data); - - g_signal_emit(self, signals[DEFAULT_ADAPTER_CHANGED], 0, adapter); -} - -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) -{ - Manager *self = MANAGER(data); - - if (g_strcmp0(name, "Adapters") == 0) { - g_ptr_array_unref(self->priv->adapters); - self->priv->adapters = g_value_dup_boxed(value); - } - - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); -} - diff --git a/src/lib/bluez/manager.h b/src/lib/bluez/manager.h deleted file mode 100644 index 66ab2b6..0000000 --- a/src/lib/bluez/manager.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __MANAGER_H -#define __MANAGER_H - -#include <glib-object.h> - -#define MANAGER_DBUS_PATH "/" -#define MANAGER_DBUS_INTERFACE "org.bluez.Manager" - -/* - * Type macros - */ -#define MANAGER_TYPE (manager_get_type()) -#define MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MANAGER_TYPE, Manager)) -#define MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MANAGER_TYPE)) -#define MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MANAGER_TYPE, ManagerClass)) -#define MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MANAGER_TYPE)) -#define MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MANAGER_TYPE, ManagerClass)) - -typedef struct _Manager Manager; -typedef struct _ManagerClass ManagerClass; -typedef struct _ManagerPrivate ManagerPrivate; - -struct _Manager { - GObject parent_instance; - - /*< private >*/ - ManagerPrivate *priv; -}; - -struct _ManagerClass { - GObjectClass parent_class; -}; - -/* used by MANAGER_TYPE */ -GType manager_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -gchar *manager_default_adapter(Manager *self, GError **error); -gchar *manager_find_adapter(Manager *self, const gchar *pattern, GError **error); -GHashTable *manager_get_properties(Manager *self, GError **error); - -const GPtrArray *manager_get_adapters(Manager *self); - -#endif /* __MANAGER_H */ - diff --git a/src/lib/bluez/media.c b/src/lib/bluez/media.c new file mode 100644 index 0000000..befcae7 --- /dev/null +++ b/src/lib/bluez/media.c @@ -0,0 +1,190 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "media.h" + +#define MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), MEDIA_TYPE, MediaPrivate)) + +struct _MediaPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(Media, media, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _media_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _media_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _media_create_gdbus_proxy(Media *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void media_dispose(GObject *gobject) +{ + Media *self = MEDIA(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(media_parent_class)->dispose(gobject); +} + +static void media_finalize (GObject *gobject) +{ + Media *self = MEDIA(gobject); + G_OBJECT_CLASS(media_parent_class)->finalize(gobject); +} + +static void media_class_init(MediaClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = media_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _media_get_property; + gobject_class->set_property = _media_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Media D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void media_init(Media *self) +{ + self->priv = media_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _media_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Media *self = MEDIA(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, media_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _media_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Media *self = MEDIA(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _media_create_gdbus_proxy(self, MEDIA_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +Media *media_new(const gchar *dbus_object_path) +{ + return g_object_new(MEDIA_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _media_create_gdbus_proxy(Media *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(MEDIA_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, MEDIA_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *media_get_dbus_object_path(Media *self) +{ + g_assert(MEDIA_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void RegisterEndpoint(object endpoint, dict properties) */ +void media_register_endpoint(Media *self, const gchar *endpoint, const GVariant *properties, GError **error) +{ + g_assert(MEDIA_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RegisterEndpoint", g_variant_new ("(o@a{sv})", endpoint, properties), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void RegisterPlayer(object player, dict properties) */ +void media_register_player(Media *self, const gchar *player, const GVariant *properties, GError **error) +{ + g_assert(MEDIA_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RegisterPlayer", g_variant_new ("(o@a{sv})", player, properties), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UnregisterEndpoint(object endpoint) */ +void media_unregister_endpoint(Media *self, const gchar *endpoint, GError **error) +{ + g_assert(MEDIA_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UnregisterEndpoint", g_variant_new ("(o)", endpoint), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UnregisterPlayer(object player) */ +void media_unregister_player(Media *self, const gchar *player, GError **error) +{ + g_assert(MEDIA_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UnregisterPlayer", g_variant_new ("(o)", player), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/media.h b/src/lib/bluez/media.h new file mode 100644 index 0000000..ad508e2 --- /dev/null +++ b/src/lib/bluez/media.h @@ -0,0 +1,84 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __MEDIA_H +#define __MEDIA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define MEDIA_DBUS_SERVICE "org.bluez" +#define MEDIA_DBUS_INTERFACE "org.bluez.Media1" + +/* + * Type macros + */ +#define MEDIA_TYPE (media_get_type()) +#define MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MEDIA_TYPE, Media)) +#define MEDIA_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MEDIA_TYPE)) +#define MEDIA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MEDIA_TYPE, MediaClass)) +#define MEDIA_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MEDIA_TYPE)) +#define MEDIA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MEDIA_TYPE, MediaClass)) + +typedef struct _Media Media; +typedef struct _MediaClass MediaClass; +typedef struct _MediaPrivate MediaPrivate; + +struct _Media { + GObject parent_instance; + + /*< private >*/ + MediaPrivate *priv; +}; + +struct _MediaClass { + GObjectClass parent_class; +}; + +/* used by MEDIA_TYPE */ +GType media_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +Media *media_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *media_get_dbus_object_path(Media *self); + +void media_register_endpoint(Media *self, const gchar *endpoint, const GVariant *properties, GError **error); +void media_register_player(Media *self, const gchar *player, const GVariant *properties, GError **error); +void media_unregister_endpoint(Media *self, const gchar *endpoint, GError **error); +void media_unregister_player(Media *self, const gchar *player, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_H */ + diff --git a/src/lib/bluez/media_control.c b/src/lib/bluez/media_control.c new file mode 100644 index 0000000..5d3913f --- /dev/null +++ b/src/lib/bluez/media_control.c @@ -0,0 +1,259 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "media_control.h" + +#define MEDIA_CONTROL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), MEDIA_CONTROL_TYPE, MediaControlPrivate)) + +struct _MediaControlPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(MediaControl, media_control, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _media_control_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _media_control_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _media_control_create_gdbus_proxy(MediaControl *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void media_control_dispose(GObject *gobject) +{ + MediaControl *self = MEDIA_CONTROL(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(media_control_parent_class)->dispose(gobject); +} + +static void media_control_finalize (GObject *gobject) +{ + MediaControl *self = MEDIA_CONTROL(gobject); + G_OBJECT_CLASS(media_control_parent_class)->finalize(gobject); +} + +static void media_control_class_init(MediaControlClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = media_control_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _media_control_get_property; + gobject_class->set_property = _media_control_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "MediaControl D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void media_control_init(MediaControl *self) +{ + self->priv = media_control_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _media_control_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + MediaControl *self = MEDIA_CONTROL(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, media_control_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _media_control_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + MediaControl *self = MEDIA_CONTROL(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _media_control_create_gdbus_proxy(self, MEDIA_CONTROL_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +MediaControl *media_control_new(const gchar *dbus_object_path) +{ + return g_object_new(MEDIA_CONTROL_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _media_control_create_gdbus_proxy(MediaControl *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, MEDIA_CONTROL_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *media_control_get_dbus_object_path(MediaControl *self) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void FastForward() */ +void media_control_fast_forward(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "FastForward", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Next() */ +void media_control_next(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Next", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Pause() */ +void media_control_pause(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Pause", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Play() */ +void media_control_play(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Play", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Previous() */ +void media_control_previous(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Previous", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Rewind() */ +void media_control_rewind(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Rewind", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Stop() */ +void media_control_stop(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Stop", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void VolumeDown() */ +void media_control_volume_down(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "VolumeDown", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void VolumeUp() */ +void media_control_volume_up(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "VolumeUp", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* Properties access methods */ +GVariant *media_control_get_properties(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, MEDIA_CONTROL_DBUS_INTERFACE, error); +} + +void media_control_set_property(MediaControl *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, MEDIA_CONTROL_DBUS_INTERFACE, name, value, error); +} + +gboolean media_control_get_connected(MediaControl *self, GError **error) +{ + g_assert(MEDIA_CONTROL_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_CONTROL_DBUS_INTERFACE, "Connected", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/media_control.h b/src/lib/bluez/media_control.h new file mode 100644 index 0000000..bfc58a6 --- /dev/null +++ b/src/lib/bluez/media_control.h @@ -0,0 +1,94 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __MEDIA_CONTROL_H +#define __MEDIA_CONTROL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define MEDIA_CONTROL_DBUS_SERVICE "org.bluez" +#define MEDIA_CONTROL_DBUS_INTERFACE "org.bluez.MediaControl1" + +/* + * Type macros + */ +#define MEDIA_CONTROL_TYPE (media_control_get_type()) +#define MEDIA_CONTROL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MEDIA_CONTROL_TYPE, MediaControl)) +#define MEDIA_CONTROL_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MEDIA_CONTROL_TYPE)) +#define MEDIA_CONTROL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MEDIA_CONTROL_TYPE, MediaControlClass)) +#define MEDIA_CONTROL_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MEDIA_CONTROL_TYPE)) +#define MEDIA_CONTROL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MEDIA_CONTROL_TYPE, MediaControlClass)) + +typedef struct _MediaControl MediaControl; +typedef struct _MediaControlClass MediaControlClass; +typedef struct _MediaControlPrivate MediaControlPrivate; + +struct _MediaControl { + GObject parent_instance; + + /*< private >*/ + MediaControlPrivate *priv; +}; + +struct _MediaControlClass { + GObjectClass parent_class; +}; + +/* used by MEDIA_CONTROL_TYPE */ +GType media_control_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +MediaControl *media_control_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *media_control_get_dbus_object_path(MediaControl *self); + +void media_control_fast_forward(MediaControl *self, GError **error); +void media_control_next(MediaControl *self, GError **error); +void media_control_pause(MediaControl *self, GError **error); +void media_control_play(MediaControl *self, GError **error); +void media_control_previous(MediaControl *self, GError **error); +void media_control_rewind(MediaControl *self, GError **error); +void media_control_stop(MediaControl *self, GError **error); +void media_control_volume_down(MediaControl *self, GError **error); +void media_control_volume_up(MediaControl *self, GError **error); + +GVariant *media_control_get_properties(MediaControl *self, GError **error); +void media_control_set_property(MediaControl *self, const gchar *name, const GVariant *value, GError **error); + +gboolean media_control_get_connected(MediaControl *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_CONTROL_H */ + diff --git a/src/lib/bluez/media_player.c b/src/lib/bluez/media_player.c new file mode 100644 index 0000000..ff9141a --- /dev/null +++ b/src/lib/bluez/media_player.c @@ -0,0 +1,417 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "media_player.h" + +#define MEDIA_PLAYER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), MEDIA_PLAYER_TYPE, MediaPlayerPrivate)) + +struct _MediaPlayerPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(MediaPlayer, media_player, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _media_player_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _media_player_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _media_player_create_gdbus_proxy(MediaPlayer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void media_player_dispose(GObject *gobject) +{ + MediaPlayer *self = MEDIA_PLAYER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(media_player_parent_class)->dispose(gobject); +} + +static void media_player_finalize (GObject *gobject) +{ + MediaPlayer *self = MEDIA_PLAYER(gobject); + G_OBJECT_CLASS(media_player_parent_class)->finalize(gobject); +} + +static void media_player_class_init(MediaPlayerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = media_player_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _media_player_get_property; + gobject_class->set_property = _media_player_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "MediaPlayer D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void media_player_init(MediaPlayer *self) +{ + self->priv = media_player_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _media_player_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + MediaPlayer *self = MEDIA_PLAYER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, media_player_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _media_player_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + MediaPlayer *self = MEDIA_PLAYER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _media_player_create_gdbus_proxy(self, MEDIA_PLAYER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +MediaPlayer *media_player_new(const gchar *dbus_object_path) +{ + return g_object_new(MEDIA_PLAYER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _media_player_create_gdbus_proxy(MediaPlayer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, MEDIA_PLAYER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *media_player_get_dbus_object_path(MediaPlayer *self) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void FastForward() */ +void media_player_fast_forward(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "FastForward", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Next() */ +void media_player_next(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Next", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Pause() */ +void media_player_pause(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Pause", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Play() */ +void media_player_play(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Play", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Previous() */ +void media_player_previous(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Previous", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Rewind() */ +void media_player_rewind(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Rewind", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Stop() */ +void media_player_stop(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Stop", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* Properties access methods */ +GVariant *media_player_get_properties(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, error); +} + +void media_player_set_property(MediaPlayer *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, name, value, error); +} + +gboolean media_player_get_browsable(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Browsable", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *media_player_get_device(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Device", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *media_player_get_equalizer(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Equalizer", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +void media_player_set_equalizer(MediaPlayer *self, const gchar *value, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Equalizer", g_variant_new_string(value), error); +} + +const gchar *media_player_get_name(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Name", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +guint32 media_player_get_position(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Position", error); + if(prop == NULL) + return 0; + guint32 ret = g_variant_get_uint32(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *media_player_get_repeat(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Repeat", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +void media_player_set_repeat(MediaPlayer *self, const gchar *value, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Repeat", g_variant_new_string(value), error); +} + +const gchar *media_player_get_scan(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Scan", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +void media_player_set_scan(MediaPlayer *self, const gchar *value, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Scan", g_variant_new_string(value), error); +} + +gboolean media_player_get_searchable(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Searchable", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *media_player_get_shuffle(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Shuffle", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +void media_player_set_shuffle(MediaPlayer *self, const gchar *value, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Shuffle", g_variant_new_string(value), error); +} + +const gchar *media_player_get_status(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Status", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *media_player_get_subtype(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Subtype", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +GVariant *media_player_get_track(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Track", error); + if(prop == NULL) + return NULL; + GVariant *ret = g_variant_ref_sink(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *media_player_get_player_type(MediaPlayer *self, GError **error) +{ + g_assert(MEDIA_PLAYER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, MEDIA_PLAYER_DBUS_INTERFACE, "Type", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/media_player.h b/src/lib/bluez/media_player.h new file mode 100644 index 0000000..d0a8017 --- /dev/null +++ b/src/lib/bluez/media_player.h @@ -0,0 +1,109 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __MEDIA_PLAYER_H +#define __MEDIA_PLAYER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define MEDIA_PLAYER_DBUS_SERVICE "org.bluez" +#define MEDIA_PLAYER_DBUS_INTERFACE "org.bluez.MediaPlayer1" + +/* + * Type macros + */ +#define MEDIA_PLAYER_TYPE (media_player_get_type()) +#define MEDIA_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MEDIA_PLAYER_TYPE, MediaPlayer)) +#define MEDIA_PLAYER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MEDIA_PLAYER_TYPE)) +#define MEDIA_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MEDIA_PLAYER_TYPE, MediaPlayerClass)) +#define MEDIA_PLAYER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MEDIA_PLAYER_TYPE)) +#define MEDIA_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MEDIA_PLAYER_TYPE, MediaPlayerClass)) + +typedef struct _MediaPlayer MediaPlayer; +typedef struct _MediaPlayerClass MediaPlayerClass; +typedef struct _MediaPlayerPrivate MediaPlayerPrivate; + +struct _MediaPlayer { + GObject parent_instance; + + /*< private >*/ + MediaPlayerPrivate *priv; +}; + +struct _MediaPlayerClass { + GObjectClass parent_class; +}; + +/* used by MEDIA_PLAYER_TYPE */ +GType media_player_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +MediaPlayer *media_player_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *media_player_get_dbus_object_path(MediaPlayer *self); + +void media_player_fast_forward(MediaPlayer *self, GError **error); +void media_player_next(MediaPlayer *self, GError **error); +void media_player_pause(MediaPlayer *self, GError **error); +void media_player_play(MediaPlayer *self, GError **error); +void media_player_previous(MediaPlayer *self, GError **error); +void media_player_rewind(MediaPlayer *self, GError **error); +void media_player_stop(MediaPlayer *self, GError **error); + +GVariant *media_player_get_properties(MediaPlayer *self, GError **error); +void media_player_set_property(MediaPlayer *self, const gchar *name, const GVariant *value, GError **error); + +gboolean media_player_get_browsable(MediaPlayer *self, GError **error); +const gchar *media_player_get_device(MediaPlayer *self, GError **error); +const gchar *media_player_get_equalizer(MediaPlayer *self, GError **error); +void media_player_set_equalizer(MediaPlayer *self, const gchar *value, GError **error); +const gchar *media_player_get_name(MediaPlayer *self, GError **error); +guint32 media_player_get_position(MediaPlayer *self, GError **error); +const gchar *media_player_get_repeat(MediaPlayer *self, GError **error); +void media_player_set_repeat(MediaPlayer *self, const gchar *value, GError **error); +const gchar *media_player_get_scan(MediaPlayer *self, GError **error); +void media_player_set_scan(MediaPlayer *self, const gchar *value, GError **error); +gboolean media_player_get_searchable(MediaPlayer *self, GError **error); +const gchar *media_player_get_shuffle(MediaPlayer *self, GError **error); +void media_player_set_shuffle(MediaPlayer *self, const gchar *value, GError **error); +const gchar *media_player_get_status(MediaPlayer *self, GError **error); +const gchar *media_player_get_subtype(MediaPlayer *self, GError **error); +GVariant *media_player_get_track(MediaPlayer *self, GError **error); +// This has been renamed because 'media_player_get_type' is already used by GLib +const gchar *media_player_get_player_type(MediaPlayer *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __MEDIA_PLAYER_H */ + diff --git a/src/lib/bluez/network.c b/src/lib/bluez/network.c index 411bc0e..02a33fb 100644 --- a/src/lib/bluez/network.c +++ b/src/lib/bluez/network.c @@ -24,189 +24,83 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif - -#include <string.h> - +#include <gio/gio.h> #include <glib.h> -#include <dbus/dbus-glib.h> +#include <string.h> #include "../dbus-common.h" -#include "../marshallers.h" +#include "../properties.h" #include "network.h" #define NETWORK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), NETWORK_TYPE, NetworkPrivate)) struct _NetworkPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gboolean connected; - gchar *interface; - gchar *uuid; + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; }; -G_DEFINE_TYPE(Network, network, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE(Network, network, G_TYPE_OBJECT); enum { PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_CONNECTED, /* readonly */ - PROP_INTERFACE, /* readonly */ - PROP_UUID /* readonly */ + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ }; static void _network_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void _network_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -enum { - PROPERTY_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); +static void _network_create_gdbus_proxy(Network *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); static void network_dispose(GObject *gobject) { Network *self = NETWORK(gobject); - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self); - - /* Properties free */ - g_free(self->priv->interface); - g_free(self->priv->uuid); - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); /* Chain up to the parent class */ G_OBJECT_CLASS(network_parent_class)->dispose(gobject); } +static void network_finalize (GObject *gobject) +{ + Network *self = NETWORK(gobject); + G_OBJECT_CLASS(network_parent_class)->finalize(gobject); +} + static void network_class_init(NetworkClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->dispose = network_dispose; - g_type_class_add_private(klass, sizeof(NetworkPrivate)); - /* Properties registration */ - GParamSpec *pspec; + GParamSpec *pspec = NULL; gobject_class->get_property = _network_get_property; gobject_class->set_property = _network_set_property; - + /* object DBusObjectPath [readwrite, construct only] */ - pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Network D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); - - /* boolean Connected [readonly] */ - pspec = g_param_spec_boolean("Connected", NULL, NULL, FALSE, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_CONNECTED, pspec); - - /* string Interface [readonly] */ - pspec = g_param_spec_string("Interface", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_INTERFACE, pspec); - - /* string UUID [readonly] */ - pspec = g_param_spec_string("UUID", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_UUID, pspec); - - /* Signals registation */ - signals[PROPERTY_CHANGED] = g_signal_new("PropertyChanged", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, NULL, NULL, - g_cclosure_bt_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); + if (pspec) + g_param_spec_unref(pspec); } static void network_init(Network *self) { - self->priv = NETWORK_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - + self->priv = network_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; g_assert(system_conn != NULL); } -static void network_post_init(Network *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", NETWORK_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", NETWORK_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, NETWORK_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* PropertyChanged(string name, variant value) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "PropertyChanged", G_CALLBACK(property_changed_handler), self, NULL); - - /* Properties init */ - GHashTable *properties = network_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* boolean Connected [readonly] */ - if (g_hash_table_lookup(properties, "Connected")) { - self->priv->connected = g_value_get_boolean(g_hash_table_lookup(properties, "Connected")); - } else { - self->priv->connected = FALSE; - } - - /* string Interface [readonly] */ - if (g_hash_table_lookup(properties, "Interface")) { - self->priv->interface = g_value_dup_string(g_hash_table_lookup(properties, "Interface")); - } else { - self->priv->interface = g_strdup("undefined"); - } - - /* string UUID [readonly] */ - if (g_hash_table_lookup(properties, "UUID")) { - self->priv->uuid = g_value_dup_string(g_hash_table_lookup(properties, "UUID")); - } else { - self->priv->uuid = g_strdup("undefined"); - } - - g_hash_table_unref(properties); -} - static void _network_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { Network *self = NETWORK(object); @@ -216,18 +110,6 @@ static void _network_get_property(GObject *object, guint property_id, GValue *va g_value_set_string(value, network_get_dbus_object_path(self)); break; - case PROP_CONNECTED: - g_value_set_boolean(value, network_get_connected(self)); - break; - - case PROP_INTERFACE: - g_value_set_string(value, network_get_interface(self)); - break; - - case PROP_UUID: - g_value_set_string(value, network_get_uuid(self)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -241,7 +123,8 @@ static void _network_set_property(GObject *object, guint property_id, const GVal switch (property_id) { case PROP_DBUS_OBJECT_PATH: - network_post_init(self, g_value_get_string(value)); + self->priv->object_path = g_value_dup_string(value); + _network_create_gdbus_proxy(self, NETWORK_DBUS_SERVICE, self->priv->object_path, &error); break; default: @@ -249,88 +132,110 @@ static void _network_set_property(GObject *object, guint property_id, const GVal break; } - if (error != NULL) { + if (error != NULL) g_critical("%s", error->message); - } + g_assert(error == NULL); } -/* Methods */ +/* Constructor */ +Network *network_new(const gchar *dbus_object_path) +{ + return g_object_new(NETWORK_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} -/* string Connect(string uuid) */ -gchar *network_connect(Network *self, const gchar *uuid, GError **error) +/* Private DBus proxy creation */ +static void _network_create_gdbus_proxy(Network *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) { g_assert(NETWORK_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, NETWORK_DBUS_INTERFACE, NULL, error); - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Connect", error, G_TYPE_STRING, uuid, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID); + if(self->priv->proxy == NULL) + return; - return ret; + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); } -/* void Disconnect() */ -void network_disconnect(Network *self, GError **error) +/* Methods */ + +/* Get DBus object path */ +const gchar *network_get_dbus_object_path(Network *self) { g_assert(NETWORK_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); } -/* dict GetProperties() */ -GHashTable *network_get_properties(Network *self, GError **error) +/* string Connect(string uuid) */ +const gchar *network_connect(Network *self, const gchar *uuid, GError **error) { g_assert(NETWORK_IS(self)); - - GHashTable *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); - + const gchar *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "Connect", g_variant_new ("(s)", uuid), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_string(proxy_ret, NULL); + g_variant_unref(proxy_ret); return ret; } -/* Properties access methods */ -const gchar *network_get_dbus_object_path(Network *self) +/* void Disconnect() */ +void network_disconnect(Network *self, GError **error) { g_assert(NETWORK_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); + g_dbus_proxy_call_sync(self->priv->proxy, "Disconnect", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } -const gboolean network_get_connected(Network *self) +/* Properties access methods */ +GVariant *network_get_properties(Network *self, GError **error) { g_assert(NETWORK_IS(self)); - - return self->priv->connected; + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, NETWORK_DBUS_INTERFACE, error); } -const gchar *network_get_interface(Network *self) +void network_set_property(Network *self, const gchar *name, const GVariant *value, GError **error) { g_assert(NETWORK_IS(self)); - - return self->priv->interface; + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, NETWORK_DBUS_INTERFACE, name, value, error); } -const gchar *network_get_uuid(Network *self) +gboolean network_get_connected(Network *self, GError **error) { g_assert(NETWORK_IS(self)); - - return self->priv->uuid; + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, NETWORK_DBUS_INTERFACE, "Connected", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; } -/* Signals handlers */ -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +const gchar *network_get_interface(Network *self, GError **error) { - Network *self = NETWORK(data); - - if (g_strcmp0(name, "Connected") == 0) { - self->priv->connected = g_value_get_boolean(value); - } else if (g_strcmp0(name, "Interface") == 0) { - g_free(self->priv->interface); - self->priv->interface = g_value_dup_string(value); - } else if (g_strcmp0(name, "UUID") == 0) { - g_free(self->priv->uuid); - self->priv->uuid = g_value_dup_string(value); - } + g_assert(NETWORK_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, NETWORK_DBUS_INTERFACE, "Interface", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); +const gchar *network_get_uuid(Network *self, GError **error) +{ + g_assert(NETWORK_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, NETWORK_DBUS_INTERFACE, "UUID", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; } diff --git a/src/lib/bluez/network.h b/src/lib/bluez/network.h index ddeee5b..b8f597e 100644 --- a/src/lib/bluez/network.h +++ b/src/lib/bluez/network.h @@ -24,9 +24,14 @@ #ifndef __NETWORK_H #define __NETWORK_H +#ifdef __cplusplus +extern "C" { +#endif + #include <glib-object.h> -#define NETWORK_DBUS_INTERFACE "org.bluez.Network" +#define NETWORK_DBUS_SERVICE "org.bluez" +#define NETWORK_DBUS_INTERFACE "org.bluez.Network1" /* * Type macros @@ -57,16 +62,28 @@ struct _NetworkClass { GType network_get_type(void) G_GNUC_CONST; /* + * Constructor + */ +Network *network_new(const gchar *dbus_object_path); + +/* * Method definitions */ -gchar *network_connect(Network *self, const gchar *uuid, GError **error); +const gchar *network_get_dbus_object_path(Network *self); + +const gchar *network_connect(Network *self, const gchar *uuid, GError **error); void network_disconnect(Network *self, GError **error); -GHashTable *network_get_properties(Network *self, GError **error); -const gchar *network_get_dbus_object_path(Network *self); -const gboolean network_get_connected(Network *self); -const gchar *network_get_interface(Network *self); -const gchar *network_get_uuid(Network *self); +GVariant *network_get_properties(Network *self, GError **error); +void network_set_property(Network *self, const gchar *name, const GVariant *value, GError **error); + +gboolean network_get_connected(Network *self, GError **error); +const gchar *network_get_interface(Network *self, GError **error); +const gchar *network_get_uuid(Network *self, GError **error); + +#ifdef __cplusplus +} +#endif #endif /* __NETWORK_H */ diff --git a/src/lib/bluez/network_server.c b/src/lib/bluez/network_server.c index 3acf614..7affa42 100644 --- a/src/lib/bluez/network_server.c +++ b/src/lib/bluez/network_server.c @@ -24,107 +24,79 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif - -#include <string.h> - +#include <gio/gio.h> #include <glib.h> -#include <dbus/dbus-glib.h> +#include <string.h> #include "../dbus-common.h" -#include "../marshallers.h" +#include "../properties.h" #include "network_server.h" #define NETWORK_SERVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), NETWORK_SERVER_TYPE, NetworkServerPrivate)) struct _NetworkServerPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; + GDBusProxy *proxy; + gchar *object_path; }; -G_DEFINE_TYPE(NetworkServer, network_server, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE(NetworkServer, network_server, G_TYPE_OBJECT); enum { PROP_0, - PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ }; static void _network_server_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void _network_server_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); +static void _network_server_create_gdbus_proxy(NetworkServer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + static void network_server_dispose(GObject *gobject) { NetworkServer *self = NETWORK_SERVER(gobject); /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); /* Chain up to the parent class */ G_OBJECT_CLASS(network_server_parent_class)->dispose(gobject); } +static void network_server_finalize (GObject *gobject) +{ + NetworkServer *self = NETWORK_SERVER(gobject); + G_OBJECT_CLASS(network_server_parent_class)->finalize(gobject); +} + static void network_server_class_init(NetworkServerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->dispose = network_server_dispose; - g_type_class_add_private(klass, sizeof(NetworkServerPrivate)); - /* Properties registration */ - GParamSpec *pspec; + GParamSpec *pspec = NULL; gobject_class->get_property = _network_server_get_property; gobject_class->set_property = _network_server_set_property; - + /* object DBusObjectPath [readwrite, construct only] */ - pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "NetworkServer D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); } static void network_server_init(NetworkServer *self) { - self->priv = NETWORK_SERVER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - + self->priv = network_server_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; g_assert(system_conn != NULL); } -static void network_server_post_init(NetworkServer *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", NETWORK_SERVER_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", NETWORK_SERVER_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, NETWORK_SERVER_DBUS_INTERFACE); -} - static void _network_server_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { NetworkServer *self = NETWORK_SERVER(object); @@ -147,7 +119,8 @@ static void _network_server_set_property(GObject *object, guint property_id, con switch (property_id) { case PROP_DBUS_OBJECT_PATH: - network_server_post_init(self, g_value_get_string(value)); + self->priv->object_path = g_value_dup_string(value); + _network_server_create_gdbus_proxy(self, NETWORK_SERVER_DBUS_SERVICE, self->priv->object_path, &error); break; default: @@ -155,35 +128,49 @@ static void _network_server_set_property(GObject *object, guint property_id, con break; } - if (error != NULL) { + if (error != NULL) g_critical("%s", error->message); - } + g_assert(error == NULL); } -/* Methods */ +/* Constructor */ +NetworkServer *network_server_new(const gchar *dbus_object_path) +{ + return g_object_new(NETWORK_SERVER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} -/* void Register(string uuid, string bridge) */ -void network_server_register(NetworkServer *self, const gchar *uuid, const gchar *bridge, GError **error) +/* Private DBus proxy creation */ +static void _network_server_create_gdbus_proxy(NetworkServer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) { g_assert(NETWORK_SERVER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, NETWORK_SERVER_DBUS_INTERFACE, NULL, error); - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Register", error, G_TYPE_STRING, uuid, G_TYPE_STRING, bridge, G_TYPE_INVALID, G_TYPE_INVALID); + if(self->priv->proxy == NULL) + return; } -/* void Unregister(string uuid) */ -void network_server_unregister(NetworkServer *self, const gchar *uuid, GError **error) +/* Methods */ + +/* Get DBus object path */ +const gchar *network_server_get_dbus_object_path(NetworkServer *self) { g_assert(NETWORK_SERVER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Unregister", error, G_TYPE_STRING, uuid, G_TYPE_INVALID, G_TYPE_INVALID); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); } -/* Properties access methods */ -const gchar *network_server_get_dbus_object_path(NetworkServer *self) +/* void Register(string uuid, string bridge) */ +void network_server_register(NetworkServer *self, const gchar *uuid, const gchar *bridge, GError **error) { g_assert(NETWORK_SERVER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Register", g_variant_new ("(ss)", uuid, bridge), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); +/* void Unregister(string uuid) */ +void network_server_unregister(NetworkServer *self, const gchar *uuid, GError **error) +{ + g_assert(NETWORK_SERVER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Unregister", g_variant_new ("(s)", uuid), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); } diff --git a/src/lib/bluez/network_server.h b/src/lib/bluez/network_server.h index be2260f..51a9c31 100644 --- a/src/lib/bluez/network_server.h +++ b/src/lib/bluez/network_server.h @@ -24,9 +24,14 @@ #ifndef __NETWORK_SERVER_H #define __NETWORK_SERVER_H +#ifdef __cplusplus +extern "C" { +#endif + #include <glib-object.h> -#define NETWORK_SERVER_DBUS_INTERFACE "org.bluez.NetworkServer" +#define NETWORK_SERVER_DBUS_SERVICE "org.bluez" +#define NETWORK_SERVER_DBUS_INTERFACE "org.bluez.NetworkServer1" /* * Type macros @@ -57,12 +62,21 @@ struct _NetworkServerClass { GType network_server_get_type(void) G_GNUC_CONST; /* + * Constructor + */ +NetworkServer *network_server_new(const gchar *dbus_object_path); + +/* * Method definitions */ +const gchar *network_server_get_dbus_object_path(NetworkServer *self); + void network_server_register(NetworkServer *self, const gchar *uuid, const gchar *bridge, GError **error); void network_server_unregister(NetworkServer *self, const gchar *uuid, GError **error); -const gchar *network_server_get_dbus_object_path(NetworkServer *self); +#ifdef __cplusplus +} +#endif #endif /* __NETWORK_SERVER_H */ diff --git a/src/lib/bluez/obex/obex_agent_manager.c b/src/lib/bluez/obex/obex_agent_manager.c new file mode 100644 index 0000000..99eac4d --- /dev/null +++ b/src/lib/bluez/obex/obex_agent_manager.c @@ -0,0 +1,154 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_agent_manager.h" + +#define OBEX_AGENT_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_AGENT_MANAGER_TYPE, ObexAgentManagerPrivate)) + +struct _ObexAgentManagerPrivate { + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexAgentManager, obex_agent_manager, G_TYPE_OBJECT); + +enum { + PROP_0, +}; + +static void _obex_agent_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_agent_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_agent_manager_create_gdbus_proxy(ObexAgentManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_agent_manager_dispose(GObject *gobject) +{ + ObexAgentManager *self = OBEX_AGENT_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_agent_manager_parent_class)->dispose(gobject); +} + +static void obex_agent_manager_finalize (GObject *gobject) +{ + ObexAgentManager *self = OBEX_AGENT_MANAGER(gobject); + G_OBJECT_CLASS(obex_agent_manager_parent_class)->finalize(gobject); +} + +static void obex_agent_manager_class_init(ObexAgentManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_agent_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_agent_manager_get_property; + gobject_class->set_property = _obex_agent_manager_set_property; + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_agent_manager_init(ObexAgentManager *self) +{ + self->priv = obex_agent_manager_get_instance_private (self); + self->priv->proxy = NULL; + g_assert(session_conn != NULL); + GError *error = NULL; + _obex_agent_manager_create_gdbus_proxy(self, OBEX_AGENT_MANAGER_DBUS_SERVICE, OBEX_AGENT_MANAGER_DBUS_PATH, &error); + g_assert(error == NULL); +} + +static void _obex_agent_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexAgentManager *self = OBEX_AGENT_MANAGER(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_agent_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexAgentManager *self = OBEX_AGENT_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexAgentManager *obex_agent_manager_new() +{ + return g_object_new(OBEX_AGENT_MANAGER_TYPE, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_agent_manager_create_gdbus_proxy(ObexAgentManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_AGENT_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_AGENT_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* void RegisterAgent(object agent) */ +void obex_agent_manager_register_agent(ObexAgentManager *self, const gchar *agent, GError **error) +{ + g_assert(OBEX_AGENT_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RegisterAgent", g_variant_new ("(o)", agent), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UnregisterAgent(object agent) */ +void obex_agent_manager_unregister_agent(ObexAgentManager *self, const gchar *agent, GError **error) +{ + g_assert(OBEX_AGENT_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UnregisterAgent", g_variant_new ("(o)", agent), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/obex/obex_agent_manager.h b/src/lib/bluez/obex/obex_agent_manager.h new file mode 100644 index 0000000..3c591df --- /dev/null +++ b/src/lib/bluez/obex/obex_agent_manager.h @@ -0,0 +1,81 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_AGENT_MANAGER_H +#define __OBEX_AGENT_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_AGENT_MANAGER_DBUS_SERVICE "org.bluez.obex" +#define OBEX_AGENT_MANAGER_DBUS_INTERFACE "org.bluez.obex.AgentManager1" +#define OBEX_AGENT_MANAGER_DBUS_PATH "/org/bluez/obex" + +/* + * Type macros + */ +#define OBEX_AGENT_MANAGER_TYPE (obex_agent_manager_get_type()) +#define OBEX_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_AGENT_MANAGER_TYPE, ObexAgentManager)) +#define OBEX_AGENT_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_AGENT_MANAGER_TYPE)) +#define OBEX_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_AGENT_MANAGER_TYPE, ObexAgentManagerClass)) +#define OBEX_AGENT_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_AGENT_MANAGER_TYPE)) +#define OBEX_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_AGENT_MANAGER_TYPE, ObexAgentManagerClass)) + +typedef struct _ObexAgentManager ObexAgentManager; +typedef struct _ObexAgentManagerClass ObexAgentManagerClass; +typedef struct _ObexAgentManagerPrivate ObexAgentManagerPrivate; + +struct _ObexAgentManager { + GObject parent_instance; + + /*< private >*/ + ObexAgentManagerPrivate *priv; +}; + +struct _ObexAgentManagerClass { + GObjectClass parent_class; +}; + +/* used by OBEX_AGENT_MANAGER_TYPE */ +GType obex_agent_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexAgentManager *obex_agent_manager_new(); + +/* + * Method definitions + */ +void obex_agent_manager_register_agent(ObexAgentManager *self, const gchar *agent, GError **error); +void obex_agent_manager_unregister_agent(ObexAgentManager *self, const gchar *agent, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_AGENT_MANAGER_H */ + diff --git a/src/lib/bluez/obex/obex_client.c b/src/lib/bluez/obex/obex_client.c new file mode 100644 index 0000000..02b65bb --- /dev/null +++ b/src/lib/bluez/obex/obex_client.c @@ -0,0 +1,161 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_client.h" + +#define OBEX_CLIENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_CLIENT_TYPE, ObexClientPrivate)) + +struct _ObexClientPrivate { + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexClient, obex_client, G_TYPE_OBJECT); + +enum { + PROP_0, +}; + +static void _obex_client_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_client_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_client_create_gdbus_proxy(ObexClient *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_client_dispose(GObject *gobject) +{ + ObexClient *self = OBEX_CLIENT(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_client_parent_class)->dispose(gobject); +} + +static void obex_client_finalize (GObject *gobject) +{ + ObexClient *self = OBEX_CLIENT(gobject); + G_OBJECT_CLASS(obex_client_parent_class)->finalize(gobject); +} + +static void obex_client_class_init(ObexClientClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_client_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_client_get_property; + gobject_class->set_property = _obex_client_set_property; + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_client_init(ObexClient *self) +{ + self->priv = obex_client_get_instance_private (self); + self->priv->proxy = NULL; + g_assert(session_conn != NULL); + GError *error = NULL; + _obex_client_create_gdbus_proxy(self, OBEX_CLIENT_DBUS_SERVICE, OBEX_CLIENT_DBUS_PATH, &error); + g_assert(error == NULL); +} + +static void _obex_client_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexClient *self = OBEX_CLIENT(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_client_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexClient *self = OBEX_CLIENT(object); + GError *error = NULL; + + switch (property_id) { + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexClient *obex_client_new() +{ + return g_object_new(OBEX_CLIENT_TYPE, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_client_create_gdbus_proxy(ObexClient *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_CLIENT_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_CLIENT_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* object CreateSession(string destination, dict args) */ +const gchar *obex_client_create_session(ObexClient *self, const gchar *destination, const GVariant *args, GError **error) +{ + g_assert(OBEX_CLIENT_IS(self)); + const gchar *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "CreateSession", g_variant_new ("(s@a{sv})", destination, args), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_string(proxy_ret, NULL); + g_variant_unref(proxy_ret); + return ret; +} + +/* void RemoveSession(object session) */ +void obex_client_remove_session(ObexClient *self, const gchar *session, GError **error) +{ + g_assert(OBEX_CLIENT_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RemoveSession", g_variant_new ("(o)", session), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/obex/obex_client.h b/src/lib/bluez/obex/obex_client.h new file mode 100644 index 0000000..a9bcee9 --- /dev/null +++ b/src/lib/bluez/obex/obex_client.h @@ -0,0 +1,81 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_CLIENT_H +#define __OBEX_CLIENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_CLIENT_DBUS_SERVICE "org.bluez.obex" +#define OBEX_CLIENT_DBUS_INTERFACE "org.bluez.obex.Client1" +#define OBEX_CLIENT_DBUS_PATH "/org/bluez/obex" + +/* + * Type macros + */ +#define OBEX_CLIENT_TYPE (obex_client_get_type()) +#define OBEX_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_CLIENT_TYPE, ObexClient)) +#define OBEX_CLIENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_CLIENT_TYPE)) +#define OBEX_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_CLIENT_TYPE, ObexClientClass)) +#define OBEX_CLIENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_CLIENT_TYPE)) +#define OBEX_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_CLIENT_TYPE, ObexClientClass)) + +typedef struct _ObexClient ObexClient; +typedef struct _ObexClientClass ObexClientClass; +typedef struct _ObexClientPrivate ObexClientPrivate; + +struct _ObexClient { + GObject parent_instance; + + /*< private >*/ + ObexClientPrivate *priv; +}; + +struct _ObexClientClass { + GObjectClass parent_class; +}; + +/* used by OBEX_CLIENT_TYPE */ +GType obex_client_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexClient *obex_client_new(); + +/* + * Method definitions + */ +const gchar *obex_client_create_session(ObexClient *self, const gchar *destination, const GVariant *args, GError **error); +void obex_client_remove_session(ObexClient *self, const gchar *session, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_CLIENT_H */ + diff --git a/src/lib/bluez/obex/obex_file_transfer.c b/src/lib/bluez/obex/obex_file_transfer.c new file mode 100644 index 0000000..2d3dafe --- /dev/null +++ b/src/lib/bluez/obex/obex_file_transfer.c @@ -0,0 +1,236 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_file_transfer.h" + +#define OBEX_FILE_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_FILE_TRANSFER_TYPE, ObexFileTransferPrivate)) + +struct _ObexFileTransferPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexFileTransfer, obex_file_transfer, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_file_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_file_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_file_transfer_create_gdbus_proxy(ObexFileTransfer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_file_transfer_dispose(GObject *gobject) +{ + ObexFileTransfer *self = OBEX_FILE_TRANSFER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_file_transfer_parent_class)->dispose(gobject); +} + +static void obex_file_transfer_finalize (GObject *gobject) +{ + ObexFileTransfer *self = OBEX_FILE_TRANSFER(gobject); + G_OBJECT_CLASS(obex_file_transfer_parent_class)->finalize(gobject); +} + +static void obex_file_transfer_class_init(ObexFileTransferClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_file_transfer_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_file_transfer_get_property; + gobject_class->set_property = _obex_file_transfer_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexFileTransfer D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_file_transfer_init(ObexFileTransfer *self) +{ + self->priv = obex_file_transfer_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_file_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexFileTransfer *self = OBEX_FILE_TRANSFER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_file_transfer_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_file_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexFileTransfer *self = OBEX_FILE_TRANSFER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_file_transfer_create_gdbus_proxy(self, OBEX_FILE_TRANSFER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexFileTransfer *obex_file_transfer_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_FILE_TRANSFER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_file_transfer_create_gdbus_proxy(ObexFileTransfer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_FILE_TRANSFER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_file_transfer_get_dbus_object_path(ObexFileTransfer *self) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void ChangeFolder(string folder) */ +void obex_file_transfer_change_folder(ObexFileTransfer *self, const gchar *folder, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "ChangeFolder", g_variant_new ("(s)", folder), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void CopyFile(string sourcefile, string targetfile) */ +void obex_file_transfer_copy_file(ObexFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "CopyFile", g_variant_new ("(ss)", sourcefile, targetfile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void CreateFolder(string folder) */ +void obex_file_transfer_create_folder(ObexFileTransfer *self, const gchar *folder, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "CreateFolder", g_variant_new ("(s)", folder), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Delete(string file) */ +void obex_file_transfer_delete(ObexFileTransfer *self, const gchar *file, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Delete", g_variant_new ("(s)", file), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* object, dict GetFile(string targetfile, string sourcefile) */ +GVariant *obex_file_transfer_get_file(ObexFileTransfer *self, const gchar *targetfile, const gchar *sourcefile, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "GetFile", g_variant_new ("(ss)", targetfile, sourcefile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +/* array{dict} ListFolder() */ +GVariant *obex_file_transfer_list_folder(ObexFileTransfer *self, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "ListFolder", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +/* void MoveFile(string sourcefile, string targetfile) */ +void obex_file_transfer_move_file(ObexFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "MoveFile", g_variant_new ("(ss)", sourcefile, targetfile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* object, dict PutFile(string sourcefile, string targetfile) */ +GVariant *obex_file_transfer_put_file(ObexFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) +{ + g_assert(OBEX_FILE_TRANSFER_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "PutFile", g_variant_new ("(ss)", targetfile, sourcefile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +}
\ No newline at end of file diff --git a/src/lib/bluez/obex/obex_file_transfer.h b/src/lib/bluez/obex/obex_file_transfer.h new file mode 100644 index 0000000..a908701 --- /dev/null +++ b/src/lib/bluez/obex/obex_file_transfer.h @@ -0,0 +1,88 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_FILE_TRANSFER_H +#define __OBEX_FILE_TRANSFER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_FILE_TRANSFER_DBUS_SERVICE "org.bluez.obex" +#define OBEX_FILE_TRANSFER_DBUS_INTERFACE "org.bluez.obex.FileTransfer" + +/* + * Type macros + */ +#define OBEX_FILE_TRANSFER_TYPE (obex_file_transfer_get_type()) +#define OBEX_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_FILE_TRANSFER_TYPE, ObexFileTransfer)) +#define OBEX_FILE_TRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_FILE_TRANSFER_TYPE)) +#define OBEX_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_FILE_TRANSFER_TYPE, ObexFileTransferClass)) +#define OBEX_FILE_TRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_FILE_TRANSFER_TYPE)) +#define OBEX_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_FILE_TRANSFER_TYPE, ObexFileTransferClass)) + +typedef struct _ObexFileTransfer ObexFileTransfer; +typedef struct _ObexFileTransferClass ObexFileTransferClass; +typedef struct _ObexFileTransferPrivate ObexFileTransferPrivate; + +struct _ObexFileTransfer { + GObject parent_instance; + + /*< private >*/ + ObexFileTransferPrivate *priv; +}; + +struct _ObexFileTransferClass { + GObjectClass parent_class; +}; + +/* used by OBEX_FILE_TRANSFER_TYPE */ +GType obex_file_transfer_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexFileTransfer *obex_file_transfer_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_file_transfer_get_dbus_object_path(ObexFileTransfer *self); + +void obex_file_transfer_change_folder(ObexFileTransfer *self, const gchar *folder, GError **error); +void obex_file_transfer_copy_file(ObexFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); +void obex_file_transfer_create_folder(ObexFileTransfer *self, const gchar *folder, GError **error); +void obex_file_transfer_delete(ObexFileTransfer *self, const gchar *file, GError **error); +GVariant *obex_file_transfer_get_file(ObexFileTransfer *self, const gchar *targetfile, const gchar *sourcefile, GError **error); +GVariant *obex_file_transfer_list_folder(ObexFileTransfer *self, GError **error); +void obex_file_transfer_move_file(ObexFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); +GVariant *obex_file_transfer_put_file(ObexFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_FILE_TRANSFER_H */ + diff --git a/src/lib/bluez/obex/obex_message.c b/src/lib/bluez/obex/obex_message.c new file mode 100644 index 0000000..10947ae --- /dev/null +++ b/src/lib/bluez/obex/obex_message.c @@ -0,0 +1,380 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_message.h" + +#define OBEX_MESSAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_MESSAGE_TYPE, ObexMessagePrivate)) + +struct _ObexMessagePrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexMessage, obex_message, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_message_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_message_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_message_create_gdbus_proxy(ObexMessage *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_message_dispose(GObject *gobject) +{ + ObexMessage *self = OBEX_MESSAGE(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_message_parent_class)->dispose(gobject); +} + +static void obex_message_finalize (GObject *gobject) +{ + ObexMessage *self = OBEX_MESSAGE(gobject); + G_OBJECT_CLASS(obex_message_parent_class)->finalize(gobject); +} + +static void obex_message_class_init(ObexMessageClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_message_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_message_get_property; + gobject_class->set_property = _obex_message_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexMessage D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_message_init(ObexMessage *self) +{ + self->priv = obex_message_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_message_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexMessage *self = OBEX_MESSAGE(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_message_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_message_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexMessage *self = OBEX_MESSAGE(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_message_create_gdbus_proxy(self, OBEX_MESSAGE_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexMessage *obex_message_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_MESSAGE_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_message_create_gdbus_proxy(ObexMessage *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_MESSAGE_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "session", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_message_get_dbus_object_path(ObexMessage *self) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + + + +/* Properties access methods */ +GVariant *obex_message_get_properties(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, error); +} + +void obex_message_set_property(ObexMessage *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, name, value, error); +} + +void obex_message_set_deleted(ObexMessage *self, const gboolean value, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Deleted", g_variant_new_boolean(value), error); +} + +const gchar *obex_message_get_folder(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Folder", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +gboolean obex_message_get_priority(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Priority", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +gboolean obex_message_get_protected(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Protected", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +gboolean obex_message_get_read(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Read", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +void obex_message_set_read(ObexMessage *self, const gboolean value, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Read", g_variant_new_boolean(value), error); +} + +const gchar *obex_message_get_recipient(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Recipient", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_recipient_address(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "RecipientAddress", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_reply_to(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "ReplyTo", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_sender(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Sender", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_sender_address(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "SenderAddress", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +gboolean obex_message_get_sent(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Sent", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + +guint64 obex_message_get_size(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Size", error); + if(prop == NULL) + return 0; + guint64 ret = g_variant_get_uint64(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_status(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Status", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_subject(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Subject", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_timestamp(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Timestamp", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_message_get_message_type(ObexMessage *self, GError **error) +{ + g_assert(OBEX_MESSAGE_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_MESSAGE_DBUS_INTERFACE, "Type", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/obex/obex_message.h b/src/lib/bluez/obex/obex_message.h new file mode 100644 index 0000000..c5164c5 --- /dev/null +++ b/src/lib/bluez/obex/obex_message.h @@ -0,0 +1,101 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_MESSAGE_H +#define __OBEX_MESSAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_MESSAGE_DBUS_SERVICE "org.bluez.obex" +#define OBEX_MESSAGE_DBUS_INTERFACE "org.bluez.obex.Message1" + +/* + * Type macros + */ +#define OBEX_MESSAGE_TYPE (obex_message_get_type()) +#define OBEX_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_MESSAGE_TYPE, ObexMessage)) +#define OBEX_MESSAGE_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_MESSAGE_TYPE)) +#define OBEX_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_MESSAGE_TYPE, ObexMessageClass)) +#define OBEX_MESSAGE_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_MESSAGE_TYPE)) +#define OBEX_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_MESSAGE_TYPE, ObexMessageClass)) + +typedef struct _ObexMessage ObexMessage; +typedef struct _ObexMessageClass ObexMessageClass; +typedef struct _ObexMessagePrivate ObexMessagePrivate; + +struct _ObexMessage { + GObject parent_instance; + + /*< private >*/ + ObexMessagePrivate *priv; +}; + +struct _ObexMessageClass { + GObjectClass parent_class; +}; + +/* used by OBEX_MESSAGE_TYPE */ +GType obex_message_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexMessage *obex_message_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_message_get_dbus_object_path(ObexMessage *self); + +GVariant *obex_message_get_properties(ObexMessage *self, GError **error); +void obex_message_set_property(ObexMessage *self, const gchar *name, const GVariant *value, GError **error); + +void obex_message_set_deleted(ObexMessage *self, const gboolean value, GError **error); +const gchar *obex_message_get_folder(ObexMessage *self, GError **error); +gboolean obex_message_get_priority(ObexMessage *self, GError **error); +gboolean obex_message_get_protected(ObexMessage *self, GError **error); +gboolean obex_message_get_read(ObexMessage *self, GError **error); +void obex_message_set_read(ObexMessage *self, const gboolean value, GError **error); +const gchar *obex_message_get_recipient(ObexMessage *self, GError **error); +const gchar *obex_message_get_recipient_address(ObexMessage *self, GError **error); +const gchar *obex_message_get_reply_to(ObexMessage *self, GError **error); +const gchar *obex_message_get_sender(ObexMessage *self, GError **error); +const gchar *obex_message_get_sender_address(ObexMessage *self, GError **error); +gboolean obex_message_get_sent(ObexMessage *self, GError **error); +guint64 obex_message_get_size(ObexMessage *self, GError **error); +const gchar *obex_message_get_status(ObexMessage *self, GError **error); +const gchar *obex_message_get_subject(ObexMessage *self, GError **error); +const gchar *obex_message_get_timestamp(ObexMessage *self, GError **error); +// This has been renamed because 'obex_message_get_type' is already used by GLib +const gchar *obex_message_get_message_type(ObexMessage *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_MESSAGE_H */ + diff --git a/src/lib/bluez/obex/obex_message_access.c b/src/lib/bluez/obex/obex_message_access.c new file mode 100644 index 0000000..66f43fe --- /dev/null +++ b/src/lib/bluez/obex/obex_message_access.c @@ -0,0 +1,204 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_message_access.h" + +#define OBEX_MESSAGE_ACCESS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_MESSAGE_ACCESS_TYPE, ObexMessageAccessPrivate)) + +struct _ObexMessageAccessPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexMessageAccess, obex_message_access, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_message_access_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_message_access_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_message_access_create_gdbus_proxy(ObexMessageAccess *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_message_access_dispose(GObject *gobject) +{ + ObexMessageAccess *self = OBEX_MESSAGE_ACCESS(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_message_access_parent_class)->dispose(gobject); +} + +static void obex_message_access_finalize (GObject *gobject) +{ + ObexMessageAccess *self = OBEX_MESSAGE_ACCESS(gobject); + G_OBJECT_CLASS(obex_message_access_parent_class)->finalize(gobject); +} + +static void obex_message_access_class_init(ObexMessageAccessClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_message_access_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_message_access_get_property; + gobject_class->set_property = _obex_message_access_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexMessageAccess D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_message_access_init(ObexMessageAccess *self) +{ + self->priv = obex_message_access_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_message_access_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexMessageAccess *self = OBEX_MESSAGE_ACCESS(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_message_access_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_message_access_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexMessageAccess *self = OBEX_MESSAGE_ACCESS(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_message_access_create_gdbus_proxy(self, OBEX_MESSAGE_ACCESS_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexMessageAccess *obex_message_access_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_MESSAGE_ACCESS_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_message_access_create_gdbus_proxy(ObexMessageAccess *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_MESSAGE_ACCESS_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_MESSAGE_ACCESS_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_message_access_get_dbus_object_path(ObexMessageAccess *self) +{ + g_assert(OBEX_MESSAGE_ACCESS_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* array{string} ListFilterFields() */ +const gchar **obex_message_access_list_filter_fields(ObexMessageAccess *self, GError **error) +{ + g_assert(OBEX_MESSAGE_ACCESS_IS(self)); + const gchar **ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "ListFilterFields", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_strv(proxy_ret, NULL); + g_variant_unref(proxy_ret); + return ret; +} + +/* array{dict} ListFolders(dict filter) */ +GVariant *obex_message_access_list_folders(ObexMessageAccess *self, const GVariant *filter, GError **error) +{ + g_assert(OBEX_MESSAGE_ACCESS_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "ListFolders", g_variant_new ("(@a{sv})", filter), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +/* void SetFolder(string name) */ +void obex_message_access_set_folder(ObexMessageAccess *self, const gchar *name, GError **error) +{ + g_assert(OBEX_MESSAGE_ACCESS_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "SetFolder", g_variant_new ("(s)", name), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UpdateInbox(void) */ +void obex_message_access_update_inbox(ObexMessageAccess *self, GError **error) +{ + g_assert(OBEX_MESSAGE_ACCESS_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UpdateInbox", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/obex/obex_message_access.h b/src/lib/bluez/obex/obex_message_access.h new file mode 100644 index 0000000..f68bab2 --- /dev/null +++ b/src/lib/bluez/obex/obex_message_access.h @@ -0,0 +1,84 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_MESSAGE_ACCESS_H +#define __OBEX_MESSAGE_ACCESS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_MESSAGE_ACCESS_DBUS_SERVICE "org.bluez.obex" +#define OBEX_MESSAGE_ACCESS_DBUS_INTERFACE "org.bluez.obex.MessageAccess1" + +/* + * Type macros + */ +#define OBEX_MESSAGE_ACCESS_TYPE (obex_message_access_get_type()) +#define OBEX_MESSAGE_ACCESS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_MESSAGE_ACCESS_TYPE, ObexMessageAccess)) +#define OBEX_MESSAGE_ACCESS_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_MESSAGE_ACCESS_TYPE)) +#define OBEX_MESSAGE_ACCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_MESSAGE_ACCESS_TYPE, ObexMessageAccessClass)) +#define OBEX_MESSAGE_ACCESS_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_MESSAGE_ACCESS_TYPE)) +#define OBEX_MESSAGE_ACCESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_MESSAGE_ACCESS_TYPE, ObexMessageAccessClass)) + +typedef struct _ObexMessageAccess ObexMessageAccess; +typedef struct _ObexMessageAccessClass ObexMessageAccessClass; +typedef struct _ObexMessageAccessPrivate ObexMessageAccessPrivate; + +struct _ObexMessageAccess { + GObject parent_instance; + + /*< private >*/ + ObexMessageAccessPrivate *priv; +}; + +struct _ObexMessageAccessClass { + GObjectClass parent_class; +}; + +/* used by OBEX_MESSAGE_ACCESS_TYPE */ +GType obex_message_access_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexMessageAccess *obex_message_access_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_message_access_get_dbus_object_path(ObexMessageAccess *self); + +const gchar **obex_message_access_list_filter_fields(ObexMessageAccess *self, GError **error); +GVariant *obex_message_access_list_folders(ObexMessageAccess *self, const GVariant *filter, GError **error); +void obex_message_access_set_folder(ObexMessageAccess *self, const gchar *name, GError **error); +void obex_message_access_update_inbox(ObexMessageAccess *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_MESSAGE_ACCESS_H */ + diff --git a/src/lib/bluez/obex/obex_object_push.c b/src/lib/bluez/obex/obex_object_push.c new file mode 100644 index 0000000..a86aa36 --- /dev/null +++ b/src/lib/bluez/obex/obex_object_push.c @@ -0,0 +1,197 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_object_push.h" + +#define OBEX_OBJECT_PUSH_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_OBJECT_PUSH_TYPE, ObexObjectPushPrivate)) + +struct _ObexObjectPushPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexObjectPush, obex_object_push, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_object_push_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_object_push_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_object_push_create_gdbus_proxy(ObexObjectPush *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_object_push_dispose(GObject *gobject) +{ + ObexObjectPush *self = OBEX_OBJECT_PUSH(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_object_push_parent_class)->dispose(gobject); +} + +static void obex_object_push_finalize (GObject *gobject) +{ + ObexObjectPush *self = OBEX_OBJECT_PUSH(gobject); + G_OBJECT_CLASS(obex_object_push_parent_class)->finalize(gobject); +} + +static void obex_object_push_class_init(ObexObjectPushClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_object_push_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_object_push_get_property; + gobject_class->set_property = _obex_object_push_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexObjectPush D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_object_push_init(ObexObjectPush *self) +{ + self->priv = obex_object_push_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_object_push_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexObjectPush *self = OBEX_OBJECT_PUSH(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_object_push_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_object_push_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexObjectPush *self = OBEX_OBJECT_PUSH(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_object_push_create_gdbus_proxy(self, OBEX_OBJECT_PUSH_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexObjectPush *obex_object_push_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_OBJECT_PUSH_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_object_push_create_gdbus_proxy(ObexObjectPush *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_OBJECT_PUSH_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_OBJECT_PUSH_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_object_push_get_dbus_object_path(ObexObjectPush *self) +{ + g_assert(OBEX_OBJECT_PUSH_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +GVariant *obex_object_push_exchange_business_cards(ObexObjectPush *self, const gchar *clientfile, const gchar *targetfile, GError **error) +{ + g_assert(OBEX_OBJECT_PUSH_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "ExchangeBusinessCards", g_variant_new ("(ss)", clientfile, targetfile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +GVariant *obex_object_push_pull_business_card(ObexObjectPush *self, const gchar *targetfile, GError **error) +{ + g_assert(OBEX_OBJECT_PUSH_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "PullBusinessCard", g_variant_new ("(s)", targetfile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +GVariant *obex_object_push_send_file(ObexObjectPush *self, const gchar *sourcefile, GError **error) +{ + g_assert(OBEX_OBJECT_PUSH_IS(self)); + GVariant *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "SendFile", g_variant_new ("(s)", sourcefile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + ret = g_variant_ref_sink(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +}
\ No newline at end of file diff --git a/src/lib/bluez/obex/obex_object_push.h b/src/lib/bluez/obex/obex_object_push.h new file mode 100644 index 0000000..7fb302a --- /dev/null +++ b/src/lib/bluez/obex/obex_object_push.h @@ -0,0 +1,79 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_OBJECT_PUSH_H +#define __OBEX_OBJECT_PUSH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_OBJECT_PUSH_DBUS_SERVICE "org.bluez.obex" +#define OBEX_OBJECT_PUSH_DBUS_INTERFACE "org.bluez.obex.ObjectPush1" + +/* + * Type macros + */ +#define OBEX_OBJECT_PUSH_TYPE (obex_object_push_get_type()) +#define OBEX_OBJECT_PUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_OBJECT_PUSH_TYPE, ObexObjectPush)) +#define OBEX_OBJECT_PUSH_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_OBJECT_PUSH_TYPE)) +#define OBEX_OBJECT_PUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_OBJECT_PUSH_TYPE, ObexObjectPushClass)) +#define OBEX_OBJECT_PUSH_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_OBJECT_PUSH_TYPE)) +#define OBEX_OBJECT_PUSH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_OBJECT_PUSH_TYPE, ObexObjectPushClass)) + +typedef struct _ObexObjectPush ObexObjectPush; +typedef struct _ObexObjectPushClass ObexObjectPushClass; +typedef struct _ObexObjectPushPrivate ObexObjectPushPrivate; + +struct _ObexObjectPush { + GObject parent_instance; + + /*< private >*/ + ObexObjectPushPrivate *priv; +}; + +struct _ObexObjectPushClass { + GObjectClass parent_class; +}; + +/* used by OBEX_OBJECT_PUSH_TYPE */ +GType obex_object_push_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexObjectPush *obex_object_push_new(const gchar *dbus_object_path); +const gchar *obex_object_push_get_dbus_object_path(ObexObjectPush *self); + +GVariant *obex_object_push_exchange_business_cards(ObexObjectPush *self, const gchar *clientfile, const gchar *targetfile, GError **error); +GVariant *obex_object_push_pull_business_card(ObexObjectPush *self, const gchar *targetfile, GError **error); +GVariant *obex_object_push_send_file(ObexObjectPush *self, const gchar *sourcefile, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_OBJECT_PUSH_H */ + diff --git a/src/lib/bluez/obex/obex_phonebook_access.c b/src/lib/bluez/obex/obex_phonebook_access.c new file mode 100644 index 0000000..6d8db0c --- /dev/null +++ b/src/lib/bluez/obex/obex_phonebook_access.c @@ -0,0 +1,197 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_phonebook_access.h" + +#define OBEX_PHONEBOOK_ACCESS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_PHONEBOOK_ACCESS_TYPE, ObexPhonebookAccessPrivate)) + +struct _ObexPhonebookAccessPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexPhonebookAccess, obex_phonebook_access, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_phonebook_access_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_phonebook_access_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_phonebook_access_create_gdbus_proxy(ObexPhonebookAccess *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_phonebook_access_dispose(GObject *gobject) +{ + ObexPhonebookAccess *self = OBEX_PHONEBOOK_ACCESS(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_phonebook_access_parent_class)->dispose(gobject); +} + +static void obex_phonebook_access_finalize (GObject *gobject) +{ + ObexPhonebookAccess *self = OBEX_PHONEBOOK_ACCESS(gobject); + G_OBJECT_CLASS(obex_phonebook_access_parent_class)->finalize(gobject); +} + +static void obex_phonebook_access_class_init(ObexPhonebookAccessClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_phonebook_access_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_phonebook_access_get_property; + gobject_class->set_property = _obex_phonebook_access_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexPhonebookAccess D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_phonebook_access_init(ObexPhonebookAccess *self) +{ + self->priv = obex_phonebook_access_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_phonebook_access_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexPhonebookAccess *self = OBEX_PHONEBOOK_ACCESS(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_phonebook_access_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_phonebook_access_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexPhonebookAccess *self = OBEX_PHONEBOOK_ACCESS(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_phonebook_access_create_gdbus_proxy(self, OBEX_PHONEBOOK_ACCESS_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexPhonebookAccess *obex_phonebook_access_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_PHONEBOOK_ACCESS_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_phonebook_access_create_gdbus_proxy(ObexPhonebookAccess *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_PHONEBOOK_ACCESS_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_PHONEBOOK_ACCESS_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_phonebook_access_get_dbus_object_path(ObexPhonebookAccess *self) +{ + g_assert(OBEX_PHONEBOOK_ACCESS_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* uint16 GetSize() */ +guint16 obex_phonebook_access_get_size(ObexPhonebookAccess *self, GError **error) +{ + g_assert(OBEX_PHONEBOOK_ACCESS_IS(self)); + guint16 ret = 0; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "GetSize", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return 0; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_uint16(proxy_ret); + g_variant_unref(proxy_ret); + return ret; +} + +/* array{string} ListFilterFields() */ +const gchar **obex_phonebook_access_list_filter_fields(ObexPhonebookAccess *self, GError **error) +{ + g_assert(OBEX_PHONEBOOK_ACCESS_IS(self)); + const gchar **ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "ListFilterFields", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_strv(proxy_ret, NULL); + g_variant_unref(proxy_ret); + return ret; +} + +/* void Select(string location, string phonebook) */ +void obex_phonebook_access_select(ObexPhonebookAccess *self, const gchar *location, const gchar *phonebook, GError **error) +{ + g_assert(OBEX_PHONEBOOK_ACCESS_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Select", g_variant_new ("(ss)", location, phonebook), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/obex/obex_phonebook_access.h b/src/lib/bluez/obex/obex_phonebook_access.h new file mode 100644 index 0000000..4b7f853 --- /dev/null +++ b/src/lib/bluez/obex/obex_phonebook_access.h @@ -0,0 +1,83 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_PHONEBOOK_ACCESS_H +#define __OBEX_PHONEBOOK_ACCESS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_PHONEBOOK_ACCESS_DBUS_SERVICE "org.bluez.obex" +#define OBEX_PHONEBOOK_ACCESS_DBUS_INTERFACE "org.bluez.obex.PhonebookAccess1" + +/* + * Type macros + */ +#define OBEX_PHONEBOOK_ACCESS_TYPE (obex_phonebook_access_get_type()) +#define OBEX_PHONEBOOK_ACCESS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_PHONEBOOK_ACCESS_TYPE, ObexPhonebookAccess)) +#define OBEX_PHONEBOOK_ACCESS_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_PHONEBOOK_ACCESS_TYPE)) +#define OBEX_PHONEBOOK_ACCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_PHONEBOOK_ACCESS_TYPE, ObexPhonebookAccessClass)) +#define OBEX_PHONEBOOK_ACCESS_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_PHONEBOOK_ACCESS_TYPE)) +#define OBEX_PHONEBOOK_ACCESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_PHONEBOOK_ACCESS_TYPE, ObexPhonebookAccessClass)) + +typedef struct _ObexPhonebookAccess ObexPhonebookAccess; +typedef struct _ObexPhonebookAccessClass ObexPhonebookAccessClass; +typedef struct _ObexPhonebookAccessPrivate ObexPhonebookAccessPrivate; + +struct _ObexPhonebookAccess { + GObject parent_instance; + + /*< private >*/ + ObexPhonebookAccessPrivate *priv; +}; + +struct _ObexPhonebookAccessClass { + GObjectClass parent_class; +}; + +/* used by OBEX_PHONEBOOK_ACCESS_TYPE */ +GType obex_phonebook_access_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexPhonebookAccess *obex_phonebook_access_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_phonebook_access_get_dbus_object_path(ObexPhonebookAccess *self); + +guint16 obex_phonebook_access_get_size(ObexPhonebookAccess *self, GError **error); +const gchar **obex_phonebook_access_list_filter_fields(ObexPhonebookAccess *self, GError **error); +void obex_phonebook_access_select(ObexPhonebookAccess *self, const gchar *location, const gchar *phonebook, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_PHONEBOOK_ACCESS_H */ + diff --git a/src/lib/bluez/obex/obex_session.c b/src/lib/bluez/obex/obex_session.c new file mode 100644 index 0000000..e313ae9 --- /dev/null +++ b/src/lib/bluez/obex/obex_session.c @@ -0,0 +1,258 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_session.h" + +#define OBEX_SESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_SESSION_TYPE, ObexSessionPrivate)) + +struct _ObexSessionPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexSession, obex_session, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_session_create_gdbus_proxy(ObexSession *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_session_dispose(GObject *gobject) +{ + ObexSession *self = OBEX_SESSION(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_session_parent_class)->dispose(gobject); +} + +static void obex_session_finalize (GObject *gobject) +{ + ObexSession *self = OBEX_SESSION(gobject); + G_OBJECT_CLASS(obex_session_parent_class)->finalize(gobject); +} + +static void obex_session_class_init(ObexSessionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_session_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_session_get_property; + gobject_class->set_property = _obex_session_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexSession D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_session_init(ObexSession *self) +{ + self->priv = obex_session_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexSession *self = OBEX_SESSION(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_session_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexSession *self = OBEX_SESSION(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_session_create_gdbus_proxy(self, OBEX_SESSION_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexSession *obex_session_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_SESSION_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_session_create_gdbus_proxy(ObexSession *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_SESSION_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "session", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_session_get_dbus_object_path(ObexSession *self) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* string GetCapabilities() */ +const gchar *obex_session_get_capabilities(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + const gchar *ret = NULL; + GVariant *proxy_ret = g_dbus_proxy_call_sync(self->priv->proxy, "GetCapabilities", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (proxy_ret != NULL) + return NULL; + proxy_ret = g_variant_get_child_value(proxy_ret, 0); + ret = g_variant_get_string(proxy_ret, NULL); + g_variant_unref(proxy_ret); + return ret; +} + +/* Properties access methods */ +GVariant *obex_session_get_properties(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, error); +} + +void obex_session_set_property(ObexSession *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, name, value, error); +} + +guint8 obex_session_get_channel(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, "Channel", error); + if(prop == NULL) + return 0; + guchar ret = g_variant_get_byte(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_session_get_destination(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, "Destination", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_session_get_root(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, "Root", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_session_get_source(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, "Source", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_session_get_target(ObexSession *self, GError **error) +{ + g_assert(OBEX_SESSION_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_SESSION_DBUS_INTERFACE, "Target", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/obex/obex_session.h b/src/lib/bluez/obex/obex_session.h new file mode 100644 index 0000000..da4dca4 --- /dev/null +++ b/src/lib/bluez/obex/obex_session.h @@ -0,0 +1,90 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_SESSION_H +#define __OBEX_SESSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_SESSION_DBUS_SERVICE "org.bluez.obex" +#define OBEX_SESSION_DBUS_INTERFACE "org.bluez.obex.Session1" + +/* + * Type macros + */ +#define OBEX_SESSION_TYPE (obex_session_get_type()) +#define OBEX_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_SESSION_TYPE, ObexSession)) +#define OBEX_SESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_SESSION_TYPE)) +#define OBEX_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_SESSION_TYPE, ObexSessionClass)) +#define OBEX_SESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_SESSION_TYPE)) +#define OBEX_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_SESSION_TYPE, ObexSessionClass)) + +typedef struct _ObexSession ObexSession; +typedef struct _ObexSessionClass ObexSessionClass; +typedef struct _ObexSessionPrivate ObexSessionPrivate; + +struct _ObexSession { + GObject parent_instance; + + /*< private >*/ + ObexSessionPrivate *priv; +}; + +struct _ObexSessionClass { + GObjectClass parent_class; +}; + +/* used by OBEX_SESSION_TYPE */ +GType obex_session_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexSession *obex_session_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_session_get_dbus_object_path(ObexSession *self); + +const gchar *obex_session_get_capabilities(ObexSession *self, GError **error); + +GVariant *obex_session_get_properties(ObexSession *self, GError **error); +void obex_session_set_property(ObexSession *self, const gchar *name, const GVariant *value, GError **error); + +guint8 obex_session_get_channel(ObexSession *self, GError **error); +const gchar *obex_session_get_destination(ObexSession *self, GError **error); +const gchar *obex_session_get_root(ObexSession *self, GError **error); +const gchar *obex_session_get_source(ObexSession *self, GError **error); +const gchar *obex_session_get_target(ObexSession *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_SESSION_H */ + diff --git a/src/lib/bluez/obex/obex_synchronization.c b/src/lib/bluez/obex/obex_synchronization.c new file mode 100644 index 0000000..7c6da22 --- /dev/null +++ b/src/lib/bluez/obex/obex_synchronization.c @@ -0,0 +1,169 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_synchronization.h" + +#define OBEX_SYNCHRONIZATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_SYNCHRONIZATION_TYPE, ObexSynchronizationPrivate)) + +struct _ObexSynchronizationPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexSynchronization, obex_synchronization, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_synchronization_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_synchronization_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_synchronization_create_gdbus_proxy(ObexSynchronization *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_synchronization_dispose(GObject *gobject) +{ + ObexSynchronization *self = OBEX_SYNCHRONIZATION(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_synchronization_parent_class)->dispose(gobject); +} + +static void obex_synchronization_finalize (GObject *gobject) +{ + ObexSynchronization *self = OBEX_SYNCHRONIZATION(gobject); + G_OBJECT_CLASS(obex_synchronization_parent_class)->finalize(gobject); +} + +static void obex_synchronization_class_init(ObexSynchronizationClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_synchronization_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_synchronization_get_property; + gobject_class->set_property = _obex_synchronization_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexSynchronization D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_synchronization_init(ObexSynchronization *self) +{ + self->priv = obex_synchronization_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_synchronization_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexSynchronization *self = OBEX_SYNCHRONIZATION(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_synchronization_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_synchronization_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexSynchronization *self = OBEX_SYNCHRONIZATION(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_synchronization_create_gdbus_proxy(self, OBEX_SYNCHRONIZATION_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexSynchronization *obex_synchronization_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_SYNCHRONIZATION_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_synchronization_create_gdbus_proxy(ObexSynchronization *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_SYNCHRONIZATION_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_SYNCHRONIZATION_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_synchronization_get_dbus_object_path(ObexSynchronization *self) +{ + g_assert(OBEX_SYNCHRONIZATION_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void SetLocation(string location) */ +void obex_synchronization_set_location(ObexSynchronization *self, const gchar *location, GError **error) +{ + g_assert(OBEX_SYNCHRONIZATION_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "SetLocation", g_variant_new ("(s)", location), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/obex/obex_synchronization.h b/src/lib/bluez/obex/obex_synchronization.h new file mode 100644 index 0000000..d1fab05 --- /dev/null +++ b/src/lib/bluez/obex/obex_synchronization.h @@ -0,0 +1,81 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_SYNCHRONIZATION_H +#define __OBEX_SYNCHRONIZATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_SYNCHRONIZATION_DBUS_SERVICE "org.bluez.obex" +#define OBEX_SYNCHRONIZATION_DBUS_INTERFACE "org.bluez.obex.Synchronization1" + +/* + * Type macros + */ +#define OBEX_SYNCHRONIZATION_TYPE (obex_synchronization_get_type()) +#define OBEX_SYNCHRONIZATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_SYNCHRONIZATION_TYPE, ObexSynchronization)) +#define OBEX_SYNCHRONIZATION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_SYNCHRONIZATION_TYPE)) +#define OBEX_SYNCHRONIZATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_SYNCHRONIZATION_TYPE, ObexSynchronizationClass)) +#define OBEX_SYNCHRONIZATION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_SYNCHRONIZATION_TYPE)) +#define OBEX_SYNCHRONIZATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_SYNCHRONIZATION_TYPE, ObexSynchronizationClass)) + +typedef struct _ObexSynchronization ObexSynchronization; +typedef struct _ObexSynchronizationClass ObexSynchronizationClass; +typedef struct _ObexSynchronizationPrivate ObexSynchronizationPrivate; + +struct _ObexSynchronization { + GObject parent_instance; + + /*< private >*/ + ObexSynchronizationPrivate *priv; +}; + +struct _ObexSynchronizationClass { + GObjectClass parent_class; +}; + +/* used by OBEX_SYNCHRONIZATION_TYPE */ +GType obex_synchronization_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexSynchronization *obex_synchronization_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_synchronization_get_dbus_object_path(ObexSynchronization *self); + +void obex_synchronization_set_location(ObexSynchronization *self, const gchar *location, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_SYNCHRONIZATION_H */ + diff --git a/src/lib/bluez/obex/obex_transfer.c b/src/lib/bluez/obex/obex_transfer.c new file mode 100644 index 0000000..a6a165c --- /dev/null +++ b/src/lib/bluez/obex/obex_transfer.c @@ -0,0 +1,301 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../../dbus-common.h" +#include "../../properties.h" + +#include "obex_transfer.h" + +#define OBEX_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_TRANSFER_TYPE, ObexTransferPrivate)) + +struct _ObexTransferPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexTransfer, obex_transfer, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obex_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_transfer_create_gdbus_proxy(ObexTransfer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void obex_transfer_dispose(GObject *gobject) +{ + ObexTransfer *self = OBEX_TRANSFER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_transfer_parent_class)->dispose(gobject); +} + +static void obex_transfer_finalize (GObject *gobject) +{ + ObexTransfer *self = OBEX_TRANSFER(gobject); + G_OBJECT_CLASS(obex_transfer_parent_class)->finalize(gobject); +} + +static void obex_transfer_class_init(ObexTransferClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_transfer_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_transfer_get_property; + gobject_class->set_property = _obex_transfer_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ObexTransfer D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_transfer_init(ObexTransfer *self) +{ + self->priv = obex_transfer_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(session_conn != NULL); +} + +static void _obex_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexTransfer *self = OBEX_TRANSFER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obex_transfer_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexTransfer *self = OBEX_TRANSFER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _obex_transfer_create_gdbus_proxy(self, OBEX_TRANSFER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ObexTransfer *obex_transfer_new(const gchar *dbus_object_path) +{ + return g_object_new(OBEX_TRANSFER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _obex_transfer_create_gdbus_proxy(ObexTransfer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, OBEX_TRANSFER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "session", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *obex_transfer_get_dbus_object_path(ObexTransfer *self) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void Cancel() */ +void obex_transfer_cancel(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Cancel", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Resume() */ +void obex_transfer_resume(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Resume", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void Suspend() */ +void obex_transfer_suspend(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Suspend", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* Properties access methods */ +GVariant *obex_transfer_get_properties(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, error); +} + +void obex_transfer_set_property(ObexTransfer *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, name, value, error); +} + +const gchar *obex_transfer_get_filename(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Filename", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_transfer_get_name(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Name", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_transfer_get_session(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Session", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +guint64 obex_transfer_get_size(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Size", error); + if(prop == NULL) + return 0; + guint64 ret = g_variant_get_uint64(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_transfer_get_status(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Status", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +guint64 obex_transfer_get_time(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Time", error); + if(prop == NULL) + return 0; + guint64 ret = g_variant_get_uint64(prop); + g_variant_unref(prop); + return ret; +} + +guint64 obex_transfer_get_transferred(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Transferred", error); + if(prop == NULL) + return 0; + guint64 ret = g_variant_get_uint64(prop); + g_variant_unref(prop); + return ret; +} + +const gchar *obex_transfer_get_transfer_type(ObexTransfer *self, GError **error) +{ + g_assert(OBEX_TRANSFER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, OBEX_TRANSFER_DBUS_INTERFACE, "Type", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/obex/obex_transfer.h b/src/lib/bluez/obex/obex_transfer.h new file mode 100644 index 0000000..7996b08 --- /dev/null +++ b/src/lib/bluez/obex/obex_transfer.h @@ -0,0 +1,96 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEX_TRANSFER_H +#define __OBEX_TRANSFER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_TRANSFER_DBUS_SERVICE "org.bluez.obex" +#define OBEX_TRANSFER_DBUS_INTERFACE "org.bluez.obex.Transfer1" + +/* + * Type macros + */ +#define OBEX_TRANSFER_TYPE (obex_transfer_get_type()) +#define OBEX_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_TRANSFER_TYPE, ObexTransfer)) +#define OBEX_TRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_TRANSFER_TYPE)) +#define OBEX_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_TRANSFER_TYPE, ObexTransferClass)) +#define OBEX_TRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_TRANSFER_TYPE)) +#define OBEX_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_TRANSFER_TYPE, ObexTransferClass)) + +typedef struct _ObexTransfer ObexTransfer; +typedef struct _ObexTransferClass ObexTransferClass; +typedef struct _ObexTransferPrivate ObexTransferPrivate; + +struct _ObexTransfer { + GObject parent_instance; + + /*< private >*/ + ObexTransferPrivate *priv; +}; + +struct _ObexTransferClass { + GObjectClass parent_class; +}; + +/* used by OBEX_TRANSFER_TYPE */ +GType obex_transfer_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ObexTransfer *obex_transfer_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *obex_transfer_get_dbus_object_path(ObexTransfer *self); + +void obex_transfer_cancel(ObexTransfer *self, GError **error); +void obex_transfer_resume(ObexTransfer *self, GError **error); +void obex_transfer_suspend(ObexTransfer *self, GError **error); + +GVariant *obex_transfer_get_properties(ObexTransfer *self, GError **error); +void obex_transfer_set_property(ObexTransfer *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *obex_transfer_get_filename(ObexTransfer *self, GError **error); +const gchar *obex_transfer_get_name(ObexTransfer *self, GError **error); +const gchar *obex_transfer_get_session(ObexTransfer *self, GError **error); +guint64 obex_transfer_get_size(ObexTransfer *self, GError **error); +const gchar *obex_transfer_get_status(ObexTransfer *self, GError **error); +guint64 obex_transfer_get_time(ObexTransfer *self, GError **error); +guint64 obex_transfer_get_transferred(ObexTransfer *self, GError **error); +// This has been renamed because 'obex_transfer_get_type' is already used by GLib +const gchar *obex_transfer_get_transfer_type(ObexTransfer *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_TRANSFER_H */ + diff --git a/src/lib/bluez/profile_manager.c b/src/lib/bluez/profile_manager.c new file mode 100644 index 0000000..4857338 --- /dev/null +++ b/src/lib/bluez/profile_manager.c @@ -0,0 +1,154 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "profile_manager.h" + +#define PROFILE_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PROFILE_MANAGER_TYPE, ProfileManagerPrivate)) + +struct _ProfileManagerPrivate { + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ProfileManager, profile_manager, G_TYPE_OBJECT); + +enum { + PROP_0, +}; + +static void _profile_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _profile_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _profile_manager_create_gdbus_proxy(ProfileManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void profile_manager_dispose(GObject *gobject) +{ + ProfileManager *self = PROFILE_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Chain up to the parent class */ + G_OBJECT_CLASS(profile_manager_parent_class)->dispose(gobject); +} + +static void profile_manager_finalize (GObject *gobject) +{ + ProfileManager *self = PROFILE_MANAGER(gobject); + G_OBJECT_CLASS(profile_manager_parent_class)->finalize(gobject); +} + +static void profile_manager_class_init(ProfileManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = profile_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _profile_manager_get_property; + gobject_class->set_property = _profile_manager_set_property; + if (pspec) + g_param_spec_unref(pspec); +} + +static void profile_manager_init(ProfileManager *self) +{ + self->priv = profile_manager_get_instance_private (self); + self->priv->proxy = NULL; + g_assert(system_conn != NULL); + GError *error = NULL; + _profile_manager_create_gdbus_proxy(self, PROFILE_MANAGER_DBUS_SERVICE, PROFILE_MANAGER_DBUS_PATH, &error); + g_assert(error == NULL); +} + +static void _profile_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ProfileManager *self = PROFILE_MANAGER(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _profile_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ProfileManager *self = PROFILE_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ProfileManager *profile_manager_new() +{ + return g_object_new(PROFILE_MANAGER_TYPE, NULL); +} + +/* Private DBus proxy creation */ +static void _profile_manager_create_gdbus_proxy(ProfileManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(PROFILE_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, PROFILE_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* void RegisterProfile(object profile, string uuid, dict options) */ +void profile_manager_register_profile(ProfileManager *self, const gchar *profile, const gchar *uuid, const GVariant *options, GError **error) +{ + g_assert(PROFILE_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "RegisterProfile", g_variant_new ("(os@a{sv})", profile, uuid, options), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* void UnregisterProfile(object profile) */ +void profile_manager_unregister_profile(ProfileManager *self, const gchar *profile, GError **error) +{ + g_assert(PROFILE_MANAGER_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "UnregisterProfile", g_variant_new ("(o)", profile), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + diff --git a/src/lib/bluez/profile_manager.h b/src/lib/bluez/profile_manager.h new file mode 100644 index 0000000..ed72105 --- /dev/null +++ b/src/lib/bluez/profile_manager.h @@ -0,0 +1,81 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __PROFILE_MANAGER_H +#define __PROFILE_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define PROFILE_MANAGER_DBUS_SERVICE "org.bluez" +#define PROFILE_MANAGER_DBUS_INTERFACE "org.bluez.ProfileManager1" +#define PROFILE_MANAGER_DBUS_PATH "/org/bluez" + +/* + * Type macros + */ +#define PROFILE_MANAGER_TYPE (profile_manager_get_type()) +#define PROFILE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PROFILE_MANAGER_TYPE, ProfileManager)) +#define PROFILE_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PROFILE_MANAGER_TYPE)) +#define PROFILE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PROFILE_MANAGER_TYPE, ProfileManagerClass)) +#define PROFILE_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PROFILE_MANAGER_TYPE)) +#define PROFILE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PROFILE_MANAGER_TYPE, ProfileManagerClass)) + +typedef struct _ProfileManager ProfileManager; +typedef struct _ProfileManagerClass ProfileManagerClass; +typedef struct _ProfileManagerPrivate ProfileManagerPrivate; + +struct _ProfileManager { + GObject parent_instance; + + /*< private >*/ + ProfileManagerPrivate *priv; +}; + +struct _ProfileManagerClass { + GObjectClass parent_class; +}; + +/* used by PROFILE_MANAGER_TYPE */ +GType profile_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ProfileManager *profile_manager_new(); + +/* + * Method definitions + */ +void profile_manager_register_profile(ProfileManager *self, const gchar *profile, const gchar *uuid, const GVariant *options, GError **error); +void profile_manager_unregister_profile(ProfileManager *self, const gchar *profile, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __PROFILE_MANAGER_H */ + diff --git a/src/lib/bluez/proximity_monitor.c b/src/lib/bluez/proximity_monitor.c new file mode 100644 index 0000000..95cc1d8 --- /dev/null +++ b/src/lib/bluez/proximity_monitor.c @@ -0,0 +1,236 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "proximity_monitor.h" + +#define PROXIMITY_MONITOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PROXIMITY_MONITOR_TYPE, ProximityMonitorPrivate)) + +struct _ProximityMonitorPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ProximityMonitor, proximity_monitor, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _proximity_monitor_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _proximity_monitor_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _proximity_monitor_create_gdbus_proxy(ProximityMonitor *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void proximity_monitor_dispose(GObject *gobject) +{ + ProximityMonitor *self = PROXIMITY_MONITOR(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(proximity_monitor_parent_class)->dispose(gobject); +} + +static void proximity_monitor_finalize (GObject *gobject) +{ + ProximityMonitor *self = PROXIMITY_MONITOR(gobject); + G_OBJECT_CLASS(proximity_monitor_parent_class)->finalize(gobject); +} + +static void proximity_monitor_class_init(ProximityMonitorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = proximity_monitor_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _proximity_monitor_get_property; + gobject_class->set_property = _proximity_monitor_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ProximityMonitor D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void proximity_monitor_init(ProximityMonitor *self) +{ + self->priv = proximity_monitor_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _proximity_monitor_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ProximityMonitor *self = PROXIMITY_MONITOR(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, proximity_monitor_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _proximity_monitor_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ProximityMonitor *self = PROXIMITY_MONITOR(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _proximity_monitor_create_gdbus_proxy(self, PROXIMITY_MONITOR_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ProximityMonitor *proximity_monitor_new(const gchar *dbus_object_path) +{ + return g_object_new(PROXIMITY_MONITOR_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _proximity_monitor_create_gdbus_proxy(ProximityMonitor *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, PROXIMITY_MONITOR_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *proximity_monitor_get_dbus_object_path(ProximityMonitor *self) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + + + +/* Properties access methods */ +GVariant *proximity_monitor_get_properties(ProximityMonitor *self, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, error); +} + +void proximity_monitor_set_property(ProximityMonitor *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, name, value, error); +} + +const gchar *proximity_monitor_get_immediate_alert_level(ProximityMonitor *self, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, "ImmediateAlertLevel", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +void proximity_monitor_set_immediate_alert_level(ProximityMonitor *self, const gchar *value, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, "ImmediateAlertLevel", g_variant_new_string(value), error); +} + +const gchar *proximity_monitor_get_link_loss_alert_level(ProximityMonitor *self, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, "LinkLossAlertLevel", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +void proximity_monitor_set_link_loss_alert_level(ProximityMonitor *self, const gchar *value, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, "LinkLossAlertLevel", g_variant_new_string(value), error); +} + +const gchar *proximity_monitor_get_signal_level(ProximityMonitor *self, GError **error) +{ + g_assert(PROXIMITY_MONITOR_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, PROXIMITY_MONITOR_DBUS_INTERFACE, "SignalLevel", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/proximity_monitor.h b/src/lib/bluez/proximity_monitor.h new file mode 100644 index 0000000..ffa5df2 --- /dev/null +++ b/src/lib/bluez/proximity_monitor.h @@ -0,0 +1,88 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __PROXIMITY_MONITOR_H +#define __PROXIMITY_MONITOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define PROXIMITY_MONITOR_DBUS_SERVICE "org.bluez" +#define PROXIMITY_MONITOR_DBUS_INTERFACE "org.bluez.ProximityMonitor1" + +/* + * Type macros + */ +#define PROXIMITY_MONITOR_TYPE (proximity_monitor_get_type()) +#define PROXIMITY_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PROXIMITY_MONITOR_TYPE, ProximityMonitor)) +#define PROXIMITY_MONITOR_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PROXIMITY_MONITOR_TYPE)) +#define PROXIMITY_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PROXIMITY_MONITOR_TYPE, ProximityMonitorClass)) +#define PROXIMITY_MONITOR_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PROXIMITY_MONITOR_TYPE)) +#define PROXIMITY_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PROXIMITY_MONITOR_TYPE, ProximityMonitorClass)) + +typedef struct _ProximityMonitor ProximityMonitor; +typedef struct _ProximityMonitorClass ProximityMonitorClass; +typedef struct _ProximityMonitorPrivate ProximityMonitorPrivate; + +struct _ProximityMonitor { + GObject parent_instance; + + /*< private >*/ + ProximityMonitorPrivate *priv; +}; + +struct _ProximityMonitorClass { + GObjectClass parent_class; +}; + +/* used by PROXIMITY_MONITOR_TYPE */ +GType proximity_monitor_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ProximityMonitor *proximity_monitor_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *proximity_monitor_get_dbus_object_path(ProximityMonitor *self); + +GVariant *proximity_monitor_get_properties(ProximityMonitor *self, GError **error); +void proximity_monitor_set_property(ProximityMonitor *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *proximity_monitor_get_immediate_alert_level(ProximityMonitor *self, GError **error); +void proximity_monitor_set_immediate_alert_level(ProximityMonitor *self, const gchar *value, GError **error); +const gchar *proximity_monitor_get_link_loss_alert_level(ProximityMonitor *self, GError **error); +void proximity_monitor_set_link_loss_alert_level(ProximityMonitor *self, const gchar *value, GError **error); +const gchar *proximity_monitor_get_signal_level(ProximityMonitor *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __PROXIMITY_MONITOR_H */ + diff --git a/src/lib/bluez/proximity_reporter.c b/src/lib/bluez/proximity_reporter.c new file mode 100644 index 0000000..2b6a2b0 --- /dev/null +++ b/src/lib/bluez/proximity_reporter.c @@ -0,0 +1,210 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "proximity_reporter.h" + +#define PROXIMITY_REPORTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PROXIMITY_REPORTER_TYPE, ProximityReporterPrivate)) + +struct _ProximityReporterPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ProximityReporter, proximity_reporter, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _proximity_reporter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _proximity_reporter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _proximity_reporter_create_gdbus_proxy(ProximityReporter *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void proximity_reporter_dispose(GObject *gobject) +{ + ProximityReporter *self = PROXIMITY_REPORTER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(proximity_reporter_parent_class)->dispose(gobject); +} + +static void proximity_reporter_finalize (GObject *gobject) +{ + ProximityReporter *self = PROXIMITY_REPORTER(gobject); + G_OBJECT_CLASS(proximity_reporter_parent_class)->finalize(gobject); +} + +static void proximity_reporter_class_init(ProximityReporterClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = proximity_reporter_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _proximity_reporter_get_property; + gobject_class->set_property = _proximity_reporter_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ProximityReporter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void proximity_reporter_init(ProximityReporter *self) +{ + self->priv = proximity_reporter_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _proximity_reporter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ProximityReporter *self = PROXIMITY_REPORTER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, proximity_reporter_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _proximity_reporter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ProximityReporter *self = PROXIMITY_REPORTER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _proximity_reporter_create_gdbus_proxy(self, PROXIMITY_REPORTER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ProximityReporter *proximity_reporter_new(const gchar *dbus_object_path) +{ + return g_object_new(PROXIMITY_REPORTER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _proximity_reporter_create_gdbus_proxy(ProximityReporter *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(PROXIMITY_REPORTER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, PROXIMITY_REPORTER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *proximity_reporter_get_dbus_object_path(ProximityReporter *self) +{ + g_assert(PROXIMITY_REPORTER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + + + +/* Properties access methods */ +GVariant *proximity_reporter_get_properties(ProximityReporter *self, GError **error) +{ + g_assert(PROXIMITY_REPORTER_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, PROXIMITY_REPORTER_DBUS_INTERFACE, error); +} + +void proximity_reporter_set_property(ProximityReporter *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(PROXIMITY_REPORTER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, PROXIMITY_REPORTER_DBUS_INTERFACE, name, value, error); +} + +const gchar *proximity_reporter_get_immediate_alert_level(ProximityReporter *self, GError **error) +{ + g_assert(PROXIMITY_REPORTER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, PROXIMITY_REPORTER_DBUS_INTERFACE, "ImmediateAlertLevel", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + +const gchar *proximity_reporter_get_link_loss_alert_level(ProximityReporter *self, GError **error) +{ + g_assert(PROXIMITY_REPORTER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, PROXIMITY_REPORTER_DBUS_INTERFACE, "LinkLossAlertLevel", error); + if(prop == NULL) + return NULL; + const gchar *ret = g_variant_get_string(prop, NULL); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/proximity_reporter.h b/src/lib/bluez/proximity_reporter.h new file mode 100644 index 0000000..99a2498 --- /dev/null +++ b/src/lib/bluez/proximity_reporter.h @@ -0,0 +1,85 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __PROXIMITY_REPORTER_H +#define __PROXIMITY_REPORTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define PROXIMITY_REPORTER_DBUS_SERVICE "org.bluez" +#define PROXIMITY_REPORTER_DBUS_INTERFACE "org.bluez.ProximityReporter1" + +/* + * Type macros + */ +#define PROXIMITY_REPORTER_TYPE (proximity_reporter_get_type()) +#define PROXIMITY_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PROXIMITY_REPORTER_TYPE, ProximityReporter)) +#define PROXIMITY_REPORTER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PROXIMITY_REPORTER_TYPE)) +#define PROXIMITY_REPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PROXIMITY_REPORTER_TYPE, ProximityReporterClass)) +#define PROXIMITY_REPORTER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PROXIMITY_REPORTER_TYPE)) +#define PROXIMITY_REPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PROXIMITY_REPORTER_TYPE, ProximityReporterClass)) + +typedef struct _ProximityReporter ProximityReporter; +typedef struct _ProximityReporterClass ProximityReporterClass; +typedef struct _ProximityReporterPrivate ProximityReporterPrivate; + +struct _ProximityReporter { + GObject parent_instance; + + /*< private >*/ + ProximityReporterPrivate *priv; +}; + +struct _ProximityReporterClass { + GObjectClass parent_class; +}; + +/* used by PROXIMITY_REPORTER_TYPE */ +GType proximity_reporter_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ProximityReporter *proximity_reporter_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *proximity_reporter_get_dbus_object_path(ProximityReporter *self); + +GVariant *proximity_reporter_get_properties(ProximityReporter *self, GError **error); +void proximity_reporter_set_property(ProximityReporter *self, const gchar *name, const GVariant *value, GError **error); + +const gchar *proximity_reporter_get_immediate_alert_level(ProximityReporter *self, GError **error); +const gchar *proximity_reporter_get_link_loss_alert_level(ProximityReporter *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __PROXIMITY_REPORTER_H */ + diff --git a/src/lib/bluez/serial.c b/src/lib/bluez/serial.c deleted file mode 100644 index 03f9e4e..0000000 --- a/src/lib/bluez/serial.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib.h> -#include <dbus/dbus-glib.h> - -#include "../dbus-common.h" -#include "../marshallers.h" - -#include "serial.h" - -#define SERIAL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), SERIAL_TYPE, SerialPrivate)) - -struct _SerialPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; -}; - -G_DEFINE_TYPE(Serial, serial, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ -}; - -static void _serial_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _serial_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -static void serial_dispose(GObject *gobject) -{ - Serial *self = SERIAL(gobject); - - /* Proxy free */ - g_object_unref(self->priv->dbus_g_proxy); - - /* Introspection data free */ - g_free(self->priv->introspection_xml); - g_object_unref(self->priv->introspection_g_proxy); - - /* Chain up to the parent class */ - G_OBJECT_CLASS(serial_parent_class)->dispose(gobject); -} - -static void serial_class_init(SerialClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = serial_dispose; - - g_type_class_add_private(klass, sizeof(SerialPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _serial_get_property; - gobject_class->set_property = _serial_set_property; - - /* object DBusObjectPath [readwrite, construct only] */ - pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); -} - -static void serial_init(Serial *self) -{ - self->priv = SERIAL_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(system_conn != NULL); -} - -static void serial_post_init(Serial *self, const gchar *dbus_object_path) -{ - g_assert(dbus_object_path != NULL); - g_assert(strlen(dbus_object_path) > 0); - g_assert(self->priv->dbus_g_proxy == NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, "org.freedesktop.DBus.Introspectable"); - self->priv->introspection_xml = NULL; - if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", SERIAL_DBUS_INTERFACE, "\">", NULL); - if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { - g_critical("Interface \"%s\" does not exist in \"%s\"", SERIAL_DBUS_INTERFACE, dbus_object_path); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(system_conn, "org.bluez", dbus_object_path, SERIAL_DBUS_INTERFACE); -} - -static void _serial_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - Serial *self = SERIAL(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, serial_get_dbus_object_path(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _serial_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - Serial *self = SERIAL(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - serial_post_init(self, g_value_get_string(value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } - - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); -} - -/* Methods */ - -/* string Connect(string pattern) */ -gchar *serial_connect(Serial *self, const gchar *pattern, GError **error) -{ - g_assert(SERIAL_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Connect", error, G_TYPE_STRING, pattern, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID); - - return ret; -} - -/* void Disconnect(string device) */ -void serial_disconnect(Serial *self, const gchar *device, GError **error) -{ - g_assert(SERIAL_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_STRING, device, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* Properties access methods */ -const gchar *serial_get_dbus_object_path(Serial *self) -{ - g_assert(SERIAL_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - diff --git a/src/lib/bluez/serial.h b/src/lib/bluez/serial.h deleted file mode 100644 index d9f850b..0000000 --- a/src/lib/bluez/serial.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * bluez-tools - a set of tools to manage bluetooth devices for linux - * - * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __SERIAL_H -#define __SERIAL_H - -#include <glib-object.h> - -#define SERIAL_DBUS_INTERFACE "org.bluez.Serial" - -/* - * Type macros - */ -#define SERIAL_TYPE (serial_get_type()) -#define SERIAL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SERIAL_TYPE, Serial)) -#define SERIAL_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SERIAL_TYPE)) -#define SERIAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SERIAL_TYPE, SerialClass)) -#define SERIAL_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SERIAL_TYPE)) -#define SERIAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SERIAL_TYPE, SerialClass)) - -typedef struct _Serial Serial; -typedef struct _SerialClass SerialClass; -typedef struct _SerialPrivate SerialPrivate; - -struct _Serial { - GObject parent_instance; - - /*< private >*/ - SerialPrivate *priv; -}; - -struct _SerialClass { - GObjectClass parent_class; -}; - -/* used by SERIAL_TYPE */ -GType serial_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -gchar *serial_connect(Serial *self, const gchar *pattern, GError **error); -void serial_disconnect(Serial *self, const gchar *device, GError **error); - -const gchar *serial_get_dbus_object_path(Serial *self); - -#endif /* __SERIAL_H */ - diff --git a/src/lib/bluez/sim_access.c b/src/lib/bluez/sim_access.c new file mode 100644 index 0000000..2c585c7 --- /dev/null +++ b/src/lib/bluez/sim_access.c @@ -0,0 +1,203 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "sim_access.h" + +#define SIM_ACCESS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), SIM_ACCESS_TYPE, SimAccessPrivate)) + +struct _SimAccessPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(SimAccess, sim_access, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _sim_access_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _sim_access_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _sim_access_create_gdbus_proxy(SimAccess *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void sim_access_dispose(GObject *gobject) +{ + SimAccess *self = SIM_ACCESS(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(sim_access_parent_class)->dispose(gobject); +} + +static void sim_access_finalize (GObject *gobject) +{ + SimAccess *self = SIM_ACCESS(gobject); + G_OBJECT_CLASS(sim_access_parent_class)->finalize(gobject); +} + +static void sim_access_class_init(SimAccessClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = sim_access_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _sim_access_get_property; + gobject_class->set_property = _sim_access_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "SimAccess D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void sim_access_init(SimAccess *self) +{ + self->priv = sim_access_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _sim_access_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + SimAccess *self = SIM_ACCESS(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, sim_access_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _sim_access_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + SimAccess *self = SIM_ACCESS(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _sim_access_create_gdbus_proxy(self, SIM_ACCESS_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +SimAccess *sim_access_new(const gchar *dbus_object_path) +{ + return g_object_new(SIM_ACCESS_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _sim_access_create_gdbus_proxy(SimAccess *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(SIM_ACCESS_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, SIM_ACCESS_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *sim_access_get_dbus_object_path(SimAccess *self) +{ + g_assert(SIM_ACCESS_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +/* void Disconnect() */ +void sim_access_disconnect(SimAccess *self, GError **error) +{ + g_assert(SIM_ACCESS_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Disconnect", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +/* Properties access methods */ +GVariant *sim_access_get_properties(SimAccess *self, GError **error) +{ + g_assert(SIM_ACCESS_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, SIM_ACCESS_DBUS_INTERFACE, error); +} + +void sim_access_set_property(SimAccess *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(SIM_ACCESS_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, SIM_ACCESS_DBUS_INTERFACE, name, value, error); +} + +gboolean sim_access_get_connected(SimAccess *self, GError **error) +{ + g_assert(SIM_ACCESS_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, SIM_ACCESS_DBUS_INTERFACE, "Connected", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/sim_access.h b/src/lib/bluez/sim_access.h new file mode 100644 index 0000000..0c2a874 --- /dev/null +++ b/src/lib/bluez/sim_access.h @@ -0,0 +1,86 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __SIM_ACCESS_H +#define __SIM_ACCESS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define SIM_ACCESS_DBUS_SERVICE "org.bluez" +#define SIM_ACCESS_DBUS_INTERFACE "org.bluez.SimAccess1" + +/* + * Type macros + */ +#define SIM_ACCESS_TYPE (sim_access_get_type()) +#define SIM_ACCESS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SIM_ACCESS_TYPE, SimAccess)) +#define SIM_ACCESS_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SIM_ACCESS_TYPE)) +#define SIM_ACCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SIM_ACCESS_TYPE, SimAccessClass)) +#define SIM_ACCESS_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SIM_ACCESS_TYPE)) +#define SIM_ACCESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SIM_ACCESS_TYPE, SimAccessClass)) + +typedef struct _SimAccess SimAccess; +typedef struct _SimAccessClass SimAccessClass; +typedef struct _SimAccessPrivate SimAccessPrivate; + +struct _SimAccess { + GObject parent_instance; + + /*< private >*/ + SimAccessPrivate *priv; +}; + +struct _SimAccessClass { + GObjectClass parent_class; +}; + +/* used by SIM_ACCESS_TYPE */ +GType sim_access_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +SimAccess *sim_access_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *sim_access_get_dbus_object_path(SimAccess *self); + +void sim_access_disconnect(SimAccess *self, GError **error); + +GVariant *sim_access_get_properties(SimAccess *self, GError **error); +void sim_access_set_property(SimAccess *self, const gchar *name, const GVariant *value, GError **error); + +gboolean sim_access_get_connected(SimAccess *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __SIM_ACCESS_H */ + diff --git a/src/lib/bluez/thermometer.c b/src/lib/bluez/thermometer.c new file mode 100644 index 0000000..6e0bd20 --- /dev/null +++ b/src/lib/bluez/thermometer.c @@ -0,0 +1,198 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "thermometer.h" + +#define THERMOMETER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), THERMOMETER_TYPE, ThermometerPrivate)) + +struct _ThermometerPrivate { + GDBusProxy *proxy; + Properties *properties; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(Thermometer, thermometer, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _thermometer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _thermometer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _thermometer_create_gdbus_proxy(Thermometer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void thermometer_dispose(GObject *gobject) +{ + Thermometer *self = THERMOMETER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Properties free */ + g_clear_object(&self->priv->properties); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(thermometer_parent_class)->dispose(gobject); +} + +static void thermometer_finalize (GObject *gobject) +{ + Thermometer *self = THERMOMETER(gobject); + G_OBJECT_CLASS(thermometer_parent_class)->finalize(gobject); +} + +static void thermometer_class_init(ThermometerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = thermometer_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _thermometer_get_property; + gobject_class->set_property = _thermometer_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Thermometer D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void thermometer_init(Thermometer *self) +{ + self->priv = thermometer_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->properties = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _thermometer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Thermometer *self = THERMOMETER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, thermometer_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _thermometer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Thermometer *self = THERMOMETER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _thermometer_create_gdbus_proxy(self, THERMOMETER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +Thermometer *thermometer_new(const gchar *dbus_object_path) +{ + return g_object_new(THERMOMETER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _thermometer_create_gdbus_proxy(Thermometer *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(THERMOMETER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, THERMOMETER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; + + self->priv->properties = g_object_new(PROPERTIES_TYPE, "DBusType", "system", "DBusServiceName", dbus_service_name, "DBusObjectPath", dbus_object_path, NULL); + g_assert(self->priv->properties != NULL); +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *thermometer_get_dbus_object_path(Thermometer *self) +{ + g_assert(THERMOMETER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + + + +/* Properties access methods */ +GVariant *thermometer_get_properties(Thermometer *self, GError **error) +{ + g_assert(THERMOMETER_IS(self)); + g_assert(self->priv->properties != NULL); + return properties_get_all(self->priv->properties, THERMOMETER_DBUS_INTERFACE, error); +} + +void thermometer_set_property(Thermometer *self, const gchar *name, const GVariant *value, GError **error) +{ + g_assert(THERMOMETER_IS(self)); + g_assert(self->priv->properties != NULL); + properties_set(self->priv->properties, THERMOMETER_DBUS_INTERFACE, name, value, error); +} + +gboolean thermometer_get_intermediate(Thermometer *self, GError **error) +{ + g_assert(THERMOMETER_IS(self)); + g_assert(self->priv->properties != NULL); + GVariant *prop = properties_get(self->priv->properties, THERMOMETER_DBUS_INTERFACE, "Intermediate", error); + if(prop == NULL) + return FALSE; + gboolean ret = g_variant_get_boolean(prop); + g_variant_unref(prop); + return ret; +} + diff --git a/src/lib/bluez/thermometer.h b/src/lib/bluez/thermometer.h new file mode 100644 index 0000000..c3acb30 --- /dev/null +++ b/src/lib/bluez/thermometer.h @@ -0,0 +1,84 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __THERMOMETER_H +#define __THERMOMETER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define THERMOMETER_DBUS_SERVICE "org.bluez" +#define THERMOMETER_DBUS_INTERFACE "org.bluez.Thermometer1" + +/* + * Type macros + */ +#define THERMOMETER_TYPE (thermometer_get_type()) +#define THERMOMETER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), THERMOMETER_TYPE, Thermometer)) +#define THERMOMETER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), THERMOMETER_TYPE)) +#define THERMOMETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), THERMOMETER_TYPE, ThermometerClass)) +#define THERMOMETER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), THERMOMETER_TYPE)) +#define THERMOMETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), THERMOMETER_TYPE, ThermometerClass)) + +typedef struct _Thermometer Thermometer; +typedef struct _ThermometerClass ThermometerClass; +typedef struct _ThermometerPrivate ThermometerPrivate; + +struct _Thermometer { + GObject parent_instance; + + /*< private >*/ + ThermometerPrivate *priv; +}; + +struct _ThermometerClass { + GObjectClass parent_class; +}; + +/* used by THERMOMETER_TYPE */ +GType thermometer_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +Thermometer *thermometer_new(const gchar *dbus_object_path); + +/* + * Method definitions + */ +const gchar *thermometer_get_dbus_object_path(Thermometer *self); + +GVariant *thermometer_get_properties(Thermometer *self, GError **error); +void thermometer_set_property(Thermometer *self, const gchar *name, const GVariant *value, GError **error); + +gboolean thermometer_get_intermediate(Thermometer *self, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __THERMOMETER_H */ + diff --git a/src/lib/bluez/thermometer_manager.c b/src/lib/bluez/thermometer_manager.c new file mode 100644 index 0000000..1f5c376 --- /dev/null +++ b/src/lib/bluez/thermometer_manager.c @@ -0,0 +1,162 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "../dbus-common.h" +#include "../properties.h" + +#include "thermometer_manager.h" + +#define THERMOMETER_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), THERMOMETER_MANAGER_TYPE, ThermometerManagerPrivate)) + +struct _ThermometerManagerPrivate { + GDBusProxy *proxy; + gchar *object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ThermometerManager, thermometer_manager, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _thermometer_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _thermometer_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _thermometer_manager_create_gdbus_proxy(ThermometerManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error); + +static void thermometer_manager_dispose(GObject *gobject) +{ + ThermometerManager *self = THERMOMETER_MANAGER(gobject); + + /* Proxy free */ + g_clear_object (&self->priv->proxy); + /* Object path free */ + g_free(self->priv->object_path); + /* Chain up to the parent class */ + G_OBJECT_CLASS(thermometer_manager_parent_class)->dispose(gobject); +} + +static void thermometer_manager_finalize (GObject *gobject) +{ + ThermometerManager *self = THERMOMETER_MANAGER(gobject); + G_OBJECT_CLASS(thermometer_manager_parent_class)->finalize(gobject); +} + +static void thermometer_manager_class_init(ThermometerManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = thermometer_manager_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _thermometer_manager_get_property; + gobject_class->set_property = _thermometer_manager_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "ThermometerManager D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + if (pspec) + g_param_spec_unref(pspec); +} + +static void thermometer_manager_init(ThermometerManager *self) +{ + self->priv = thermometer_manager_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->object_path = NULL; + g_assert(system_conn != NULL); +} + +static void _thermometer_manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ThermometerManager *self = THERMOMETER_MANAGER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, thermometer_manager_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _thermometer_manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ThermometerManager *self = THERMOMETER_MANAGER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + self->priv->object_path = g_value_dup_string(value); + _thermometer_manager_create_gdbus_proxy(self, THERMOMETER_MANAGER_DBUS_SERVICE, self->priv->object_path, &error); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) + g_critical("%s", error->message); + + g_assert(error == NULL); +} + +/* Constructor */ +ThermometerManager *thermometer_manager_new(const gchar *dbus_object_path) +{ + return g_object_new(THERMOMETER_MANAGER_TYPE, "DBusObjectPath", dbus_object_path, NULL); +} + +/* Private DBus proxy creation */ +static void _thermometer_manager_create_gdbus_proxy(ThermometerManager *self, const gchar *dbus_service_name, const gchar *dbus_object_path, GError **error) +{ + g_assert(THERMOMETER_MANAGER_IS(self)); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, THERMOMETER_MANAGER_DBUS_INTERFACE, NULL, error); + + if(self->priv->proxy == NULL) + return; +} + +/* Methods */ + +/* Get DBus object path */ +const gchar *thermometer_manager_get_dbus_object_path(ThermometerManager *self) +{ + g_assert(THERMOMETER_MANAGER_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + diff --git a/src/lib/bluez/thermometer_manager.h b/src/lib/bluez/thermometer_manager.h new file mode 100644 index 0000000..5bed406 --- /dev/null +++ b/src/lib/bluez/thermometer_manager.h @@ -0,0 +1,75 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __THERMOMETER_MANAGER_H +#define __THERMOMETER_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define THERMOMETER_MANAGER_DBUS_SERVICE "org.bluez" +#define THERMOMETER_MANAGER_DBUS_INTERFACE "org.bluez.ThermometerManager1" + +/* + * Type macros + */ +#define THERMOMETER_MANAGER_TYPE (thermometer_manager_get_type()) +#define THERMOMETER_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), THERMOMETER_MANAGER_TYPE, ThermometerManager)) +#define THERMOMETER_MANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), THERMOMETER_MANAGER_TYPE)) +#define THERMOMETER_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), THERMOMETER_MANAGER_TYPE, ThermometerManagerClass)) +#define THERMOMETER_MANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), THERMOMETER_MANAGER_TYPE)) +#define THERMOMETER_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), THERMOMETER_MANAGER_TYPE, ThermometerManagerClass)) + +typedef struct _ThermometerManager ThermometerManager; +typedef struct _ThermometerManagerClass ThermometerManagerClass; +typedef struct _ThermometerManagerPrivate ThermometerManagerPrivate; + +struct _ThermometerManager { + GObject parent_instance; + + /*< private >*/ + ThermometerManagerPrivate *priv; +}; + +struct _ThermometerManagerClass { + GObjectClass parent_class; +}; + +/* used by THERMOMETER_MANAGER_TYPE */ +GType thermometer_manager_get_type(void) G_GNUC_CONST; + +/* + * Constructor + */ +ThermometerManager *thermometer_manager_new(const gchar *dbus_object_path); +const gchar *thermometer_manager_get_dbus_object_path(ThermometerManager *self); + +#ifdef __cplusplus +} +#endif + +#endif /* __THERMOMETER_MANAGER_H */ + |