diff options
Diffstat (limited to 'src/lib')
108 files changed, 11230 insertions, 6973 deletions
diff --git a/src/lib/agent-helper.c b/src/lib/agent-helper.c new file mode 100644 index 0000000..5269005 --- /dev/null +++ b/src/lib/agent-helper.c @@ -0,0 +1,371 @@ +/* + * + * 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 <errno.h> +#include <gio/gio.h> +#include <glib.h> +#include <string.h> + +#include "agent-helper.h" + +static const gchar *_bt_agent_introspect_xml = "<node name=\"/org/blueztools\">\n\t<interface name=\"org.bluez.Agent1\">\n\t\t<method name=\"Release\">\n\t\t</method>\n\t\t<method name=\"RequestPinCode\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"pincode\" direction=\"out\" type=\"s\"/>\n\t\t</method>\n\t\t<method name=\"DisplayPinCode\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"pincode\" direction=\"in\" type=\"s\"/>\n\t\t</method>\n\t\t<method name=\"RequestPasskey\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"passkey\" direction=\"out\" type=\"u\"/>\n\t\t</method>\n\t\t<method name=\"DisplayPasskey\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"passkey\" direction=\"in\" type=\"u\"/>\n\t\t\t<arg name=\"entered\" direction=\"in\" type=\"q\"/>\n\t\t</method>\n\t\t<method name=\"RequestConfirmation\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"passkey\" direction=\"in\" type=\"u\"/>\n\t\t</method>\n\t\t<method name=\"RequestAuthorization\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t</method>\n\t\t<method name=\"AuthorizeService\">\n\t\t\t<arg name=\"device\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"uuid\" direction=\"in\" type=\"s\"/>\n\t\t</method>\n\t\t<method name=\"Cancel\">\n\t\t</method>\n\t</interface>\n</node>\n"; +static guint _bt_agent_registration_id = 0; +static GHashTable *_pin_hash_table = NULL; +static gboolean _interactive = TRUE; +static GMainLoop *_mainloop = NULL; + +static void _bt_agent_g_destroy_notify(gpointer data); +static void _bt_agent_method_call_func(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data); +static const gchar *_find_device_pin(const gchar *device_path); + +static void _bt_agent_method_call_func(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) +{ + // g_print("%s%s\n", method_name, g_variant_print(parameters, FALSE)); + + if (g_strcmp0(method_name, "AuthorizeService") == 0) + { + // Return void + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if (g_strcmp0(method_name, "Cancel") == 0) + { + if (_interactive) + g_print("Request canceled\n"); + // Return void + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if (g_strcmp0(method_name, "DisplayPasskey") == 0) + { + GError *error = NULL; + Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL)); + const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj)); + + if (_interactive) + g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error)); + + if (error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + + g_object_unref(device_obj); + + if (_interactive) + { + g_print("Passkey: %u, entered: %u\n", g_variant_get_uint32(g_variant_get_child_value(parameters, 1)), g_variant_get_uint16(g_variant_get_child_value(parameters, 2))); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + else if (pin != NULL) + { + /* OK, device found */ + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected"); + } + else if (g_strcmp0(method_name, "DisplayPinCode") == 0) + { + GError *error = NULL; + Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL)); + const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj)); + const gchar *pincode = g_variant_get_string(g_variant_get_child_value(parameters, 1), NULL); + + if (_interactive) + g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error)); + + if (error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + + g_object_unref(device_obj); + + /* Try to use found PIN */ + if (pin != NULL) + { + if (g_strcmp0(pin, "*") == 0 || g_strcmp0(pin, pincode) == 0) + { + if (_interactive) + g_print("Pin code confirmed\n"); + g_dbus_method_invocation_return_value(invocation, NULL); + } + else + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match"); + + return; + } + else if (_interactive) + { + g_print("Confirm pin code: %s (yes/no)? ", pincode); + + gchar yn[4] = {0,}; + errno = 0; + if (scanf("%3s", yn) == EOF && errno) + g_warning("%s\n", strerror(errno)); + if(g_ascii_strcasecmp(yn, "yes") == 0 || g_ascii_strcasecmp(yn, "y") == 0) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match"); + return; + } + + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected"); + } + else if (g_strcmp0(method_name, "Release") == 0) + { + agent_need_unregister = FALSE; + + if(_mainloop) + if (g_main_loop_is_running(_mainloop)) + g_main_loop_quit(_mainloop); + + g_print("Agent released\n"); + + // Return void + g_dbus_method_invocation_return_value(invocation, NULL); + } + else if (g_strcmp0(method_name, "RequestAuthorization") == 0) + { + GError *error = NULL; + Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL)); + + if (_interactive) + g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error)); + + if(error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + + g_object_unref(device_obj); + + if (_interactive) + { + g_print("Authorize this device pairing (yes/no)? "); + gchar yn[4] = {0,}; + errno = 0; + if (scanf("%3s", yn) == EOF && errno) + g_warning("%s\n", strerror(errno)); + if(g_ascii_strcasecmp(yn, "yes") == 0 || g_ascii_strcasecmp(yn, "y") == 0) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected"); + return; + } + + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected"); + } + else if (g_strcmp0(method_name, "RequestConfirmation") == 0) + { + GError *error = NULL; + Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL)); + guint32 passkey = g_variant_get_uint32(g_variant_get_child_value(parameters, 1)); + const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj)); + + if (_interactive) + g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error)); + + if(error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + + g_object_unref(device_obj); + + /* Try to use found PIN */ + if (pin != NULL) + { + guint32 passkey_t; + sscanf(pin, "%u", &passkey_t); + + if (g_strcmp0(pin, "*") == 0 || passkey_t == passkey) + { + if (_interactive) + g_print("Passkey confirmed\n"); + g_dbus_method_invocation_return_value(invocation, NULL); + } + else + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match"); + + return; + } + else if (_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_ascii_strcasecmp(yn, "yes") == 0 || g_ascii_strcasecmp(yn, "y") == 0) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match"); + return; + } + + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match"); + } + else if (g_strcmp0(method_name, "RequestPasskey") == 0) + { + GError *error = NULL; + Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL)); + const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj)); + guint32 ret = 0; + + if (_interactive) + g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error)); + + if(error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + + g_object_unref(device_obj); + + /* Try to use found PIN */ + if (pin != NULL) + { + if (_interactive) + g_print("Passkey found\n"); + sscanf(pin, "%u", &ret); + g_dbus_method_invocation_return_value(invocation, g_variant_new_uint32(ret)); + return; + } + else if (_interactive) + { + g_print("Enter passkey: "); + errno = 0; + if (scanf("%u", &ret) == EOF && errno) + g_warning("%s\n", strerror(errno)); + g_dbus_method_invocation_return_value(invocation, g_variant_new_uint32(ret)); + return; + } + + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "No passkey inputted"); + } + else if (g_strcmp0(method_name, "RequestPinCode") == 0) + { + GError *error = NULL; + Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL)); + const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj)); + const gchar *ret = NULL; + + if (_interactive) + g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error)); + + if(error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + + g_object_unref(device_obj); + + /* Try to use found PIN */ + if (pin != NULL) + { + if (_interactive) + g_print("Passkey found\n"); + sscanf(pin, "%s", &ret); + g_dbus_method_invocation_return_value(invocation, g_variant_new_string(ret)); + return; + } + else if (_interactive) + { + g_print("Enter passkey: "); + errno = 0; + if (scanf("%s", &ret) == EOF && errno) + g_warning("%s\n", strerror(errno)); + g_dbus_method_invocation_return_value(invocation, g_variant_new_string(ret)); + return; + } + + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "No passkey inputted"); + } +} + +static void _bt_agent_g_destroy_notify(gpointer data) +{ + g_free(data); +} + +static const gchar *_find_device_pin(const gchar *device_path) +{ + if (_pin_hash_table) + { + GError *error = NULL; + Device *device = device_new(device_path); + const gchar *pin_by_addr = g_hash_table_lookup(_pin_hash_table, device_get_address(device, &error)); + const gchar *pin_by_alias = g_hash_table_lookup(_pin_hash_table, device_get_alias(device, &error)); + if(error) + { + g_critical("Failed to get remote device's MAC address: %s", error->message); + g_error_free(error); + } + g_object_unref(device); + const gchar *pin_all = g_hash_table_lookup(_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; +} + +void register_agent_callbacks(gboolean interactive_console, GHashTable *pin_dictonary, gpointer main_loop_object, GError **error) +{ + GDBusInterfaceVTable bt_agent_table; + memset(&bt_agent_table, 0x0, sizeof(bt_agent_table)); + + if(pin_dictonary) + _pin_hash_table = pin_dictonary; + if(main_loop_object) + _mainloop = (GMainLoop *) main_loop_object; + + _interactive = interactive_console; + + GDBusNodeInfo *bt_agent_node_info = g_dbus_node_info_new_for_xml(_bt_agent_introspect_xml, error); + GDBusInterfaceInfo *bt_agent_interface_info = g_dbus_node_info_lookup_interface(bt_agent_node_info, AGENT_DBUS_INTERFACE); + bt_agent_table.method_call = _bt_agent_method_call_func; + _bt_agent_registration_id = g_dbus_connection_register_object(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error), AGENT_PATH, bt_agent_interface_info, &bt_agent_table, NULL, _bt_agent_g_destroy_notify, error); + g_dbus_node_info_unref(bt_agent_node_info); +} + +void unregister_agent_callbacks(GError **error) +{ + if (_bt_agent_registration_id) + g_dbus_connection_unregister_object(g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error), _bt_agent_registration_id); +}
\ No newline at end of file diff --git a/src/lib/obexd-api.h b/src/lib/agent-helper.h index 09695f6..8e1cc85 100644 --- a/src/lib/obexd-api.h +++ b/src/lib/agent-helper.h @@ -21,31 +21,27 @@ * */ -#ifndef __OBEXD_API_H -#define __OBEXD_API_H +#ifndef __AGENT_HELPER_H +#define __AGENT_HELPER_H -#ifdef HAVE_CONFIG_H -#include <config.h> +#ifdef __cplusplus +extern "C" { #endif -/* Global includes */ -#include <glib.h> -#include <dbus/dbus-glib.h> - -#ifdef OBEX_SUPPORT -#define OBEXS_DBUS_NAME "org.openobex" -#define OBEXC_DBUS_NAME "org.openobex.client" - -/* OBEXD DBus API */ -#include "obexd/obexagent.h" -#include "obexd/obexclient.h" -#include "obexd/obexclient_file_transfer.h" -#include "obexd/obexclient_session.h" -#include "obexd/obexclient_transfer.h" -#include "obexd/obexmanager.h" -#include "obexd/obexsession.h" -#include "obexd/obextransfer.h" -#endif +#include <stdio.h> + +#include "bluez-api.h" + +#define AGENT_DBUS_INTERFACE "org.bluez.Agent1" +#define AGENT_PATH "/org/blueztools" -#endif /* __OBEXD_API_H */ +gboolean agent_need_unregister; + +void register_agent_callbacks(gboolean interactive_console, GHashTable *pin_dictonary, gpointer main_loop_object, GError **error); +void unregister_agent_callbacks(GError **error); + +#ifdef __cplusplus +} +#endif +#endif /* __AGENT_HELPER_H */
\ No newline at end of file diff --git a/src/lib/bluez-api.h b/src/lib/bluez-api.h index 241ad75..e3d5dd9 100644 --- a/src/lib/bluez-api.h +++ b/src/lib/bluez-api.h @@ -1,49 +1,55 @@ -/* - * - * 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 BLUEZ_API_H +#define BLUEZ_API_H -#ifndef __BLUEZ_API_H -#define __BLUEZ_API_H - -#ifdef HAVE_CONFIG_H -#include <config.h> +#ifdef __cplusplus +extern "C" { #endif -/* Global includes */ -#include <glib.h> -#include <dbus/dbus-glib.h> +#define BLUEZ_DBUS_SERVICE_NAME "org.bluez" +#define BLUEZ_OBEX_DBUS_SERVICE_NAME "org.bluez.obex" +#define BLUEZ_DBUS_BASE_PATH "/org/bluez" +#define BLUEZ_OBEX_DBUS_BASE_PATH "/org/bluez/obex" -#define BLUEZ_DBUS_NAME "org.bluez" +#include "manager.h" +#include "obex_agent.h" -/* BlueZ DBus API */ #include "bluez/adapter.h" -#include "bluez/agent.h" -#include "bluez/audio.h" +#include "bluez/agent_manager.h" +#include "bluez/alert.h" +#include "bluez/alert_agent.h" +#include "bluez/cycling_speed.h" +#include "bluez/cycling_speed_manager.h" #include "bluez/device.h" -#include "bluez/input.h" -#include "bluez/manager.h" +#include "bluez/health_channel.h" +#include "bluez/health_device.h" +#include "bluez/health_manager.h" +#include "bluez/heart_rate.h" +#include "bluez/heart_rate_manager.h" +#include "bluez/media.h" +#include "bluez/media_control.h" +#include "bluez/media_player.h" #include "bluez/network.h" #include "bluez/network_server.h" -#include "bluez/serial.h" +#include "bluez/obex/obex_agent_manager.h" +#include "bluez/obex/obex_client.h" +#include "bluez/obex/obex_file_transfer.h" +#include "bluez/obex/obex_message.h" +#include "bluez/obex/obex_message_access.h" +#include "bluez/obex/obex_object_push.h" +#include "bluez/obex/obex_phonebook_access.h" +#include "bluez/obex/obex_session.h" +#include "bluez/obex/obex_synchronization.h" +#include "bluez/obex/obex_transfer.h" +#include "bluez/profile_manager.h" +#include "bluez/proximity_monitor.h" +#include "bluez/proximity_reporter.h" +#include "bluez/sim_access.h" +#include "bluez/thermometer.h" +#include "bluez/thermometer_manager.h" + +#ifdef __cplusplus +} +#endif -#endif /* __BLUEZ_API_H */ +#endif /* BLUEZ_H */ 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 */ + diff --git a/src/lib/dbus-common.c b/src/lib/dbus-common.c index 1ebc56d..bca4039 100644 --- a/src/lib/dbus-common.c +++ b/src/lib/dbus-common.c @@ -1,102 +1,63 @@ -/* - * - * 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 <glib.h> -#include <dbus/dbus-glib.h> +#include <gio/gio.h> #include "bluez-api.h" -#ifdef OBEX_SUPPORT -#include "obexd-api.h" -#endif #include "dbus-common.h" -DBusGConnection *session_conn = NULL; -DBusGConnection *system_conn = NULL; +GDBusConnection *session_conn = NULL; +GDBusConnection *system_conn = NULL; static gboolean dbus_initialized = FALSE; void dbus_init() { - /* Marshallers registration - * Used for signals - */ - dbus_g_object_register_marshaller(g_cclosure_bt_marshal_VOID__STRING_BOXED, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_object_register_marshaller(g_cclosure_bt_marshal_VOID__INT_INT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); - dbus_g_object_register_marshaller(g_cclosure_bt_marshal_VOID__BOXED_BOOLEAN, G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_BOOLEAN, G_TYPE_INVALID); - - /* Agents installation */ - dbus_g_object_type_install_info(AGENT_TYPE, &dbus_glib_agent_object_info); -#ifdef OBEX_SUPPORT - dbus_g_object_type_install_info(OBEXAGENT_TYPE, &dbus_glib_obexagent_object_info); -#endif - - dbus_initialized = TRUE; + dbus_initialized = TRUE; } gboolean dbus_session_connect(GError **error) { - g_assert(dbus_initialized == TRUE); + g_assert(dbus_initialized == TRUE); - session_conn = dbus_g_bus_get(DBUS_BUS_SESSION, error); - if (!session_conn) { - return FALSE; - } + session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, error); + if (!session_conn) + { + return FALSE; + } - return TRUE; + return TRUE; } void dbus_session_disconnect() { - dbus_g_connection_unref(session_conn); + g_object_unref(session_conn); } gboolean dbus_system_connect(GError **error) { - g_assert(dbus_initialized == TRUE); + g_assert(dbus_initialized == TRUE); - system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, error); - if (!system_conn) { - return FALSE; - } + system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error); + if (!system_conn) + { + return FALSE; + } - return TRUE; + return TRUE; } void dbus_system_disconnect() { - dbus_g_connection_unref(system_conn); + g_object_unref(system_conn); } void dbus_disconnect() { - if (system_conn) - dbus_g_connection_unref(system_conn); - if (session_conn) - dbus_g_connection_unref(session_conn); + if (system_conn) + dbus_system_disconnect(); + if (session_conn) + dbus_session_disconnect(); } - diff --git a/src/lib/dbus-common.h b/src/lib/dbus-common.h index ad4e210..a9bacdf 100644 --- a/src/lib/dbus-common.h +++ b/src/lib/dbus-common.h @@ -1,38 +1,14 @@ -/* - * - * 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 DBUS_COMMON_H +#define DBUS_COMMON_H -#ifndef __DBUS_COMMON_H -#define __DBUS_COMMON_H +#ifdef __cplusplus +extern "C" { +#endif -#include <glib.h> -#include <dbus/dbus-glib.h> +#include <gio/gio.h> -#define DBUS_TYPE_G_STRING_VARIANT_HASHTABLE (dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) -#define DBUS_TYPE_G_UINT_STRING_HASHTABLE (dbus_g_type_get_map("GHashTable", G_TYPE_UINT, G_TYPE_STRING)) -#define DBUS_TYPE_G_HASH_TABLE_ARRAY (dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_STRING_VARIANT_HASHTABLE)) - -extern DBusGConnection *session_conn; -extern DBusGConnection *system_conn; +extern GDBusConnection *session_conn; +extern GDBusConnection *system_conn; void dbus_init(); gboolean dbus_session_connect(GError **error); @@ -41,5 +17,9 @@ gboolean dbus_system_connect(GError **error); void dbus_system_disconnect(); void dbus_disconnect(); -#endif /* __DBUS_COMMON_H */ +#ifdef __cplusplus +} +#endif + +#endif /* DBUS_COMMON_H */ diff --git a/src/lib/helpers.c b/src/lib/helpers.c index 9dea90f..7402807 100644 --- a/src/lib/helpers.c +++ b/src/lib/helpers.c @@ -31,81 +31,82 @@ #include <sys/stat.h> #include <errno.h> +#include <gio/gio.h> #include <glib.h> -#include <dbus/dbus-glib.h> #include "dbus-common.h" #include "helpers.h" /* UUID Name lookup table */ -typedef struct { - gchar *uuid; - gchar *name; - gchar *alt_name; +typedef struct +{ + gchar *uuid; + gchar *name; + gchar *alt_name; } uuid_name_lookup_table_t; static uuid_name_lookup_table_t uuid_name_lookup_table[] = { - {"00001000-0000-1000-8000-00805F9B34FB", "ServiceDiscoveryServer", NULL}, - {"00001001-0000-1000-8000-00805F9B34FB", "BrowseGroupDescriptor", NULL}, - {"00001002-0000-1000-8000-00805F9B34FB", "PublicBrowseGroup", NULL}, - {"00001101-0000-1000-8000-00805F9B34FB", "SerialPort", "Serial"}, - {"00001102-0000-1000-8000-00805F9B34FB", "LANAccessUsingPPP", NULL}, - {"00001103-0000-1000-8000-00805F9B34FB", "DialupNetworking", "DUN"}, - {"00001104-0000-1000-8000-00805F9B34FB", "IrMCSync", NULL}, - {"00001105-0000-1000-8000-00805F9B34FB", "OBEXObjectPush", NULL}, - {"00001106-0000-1000-8000-00805F9B34FB", "OBEXFileTransfer", NULL}, - {"00001107-0000-1000-8000-00805F9B34FB", "IrMCSyncCommand", NULL}, - {"00001108-0000-1000-8000-00805F9B34FB", "Headset", NULL}, - {"00001109-0000-1000-8000-00805F9B34FB", "CordlessTelephony", NULL}, - {"0000110A-0000-1000-8000-00805F9B34FB", "AudioSource", NULL}, - {"0000110B-0000-1000-8000-00805F9B34FB", "AudioSink", NULL}, - {"0000110C-0000-1000-8000-00805F9B34FB", "AVRemoteControlTarget", NULL}, - {"0000110D-0000-1000-8000-00805F9B34FB", "AdvancedAudioDistribution", "A2DP"}, - {"0000110E-0000-1000-8000-00805F9B34FB", "AVRemoteControl", NULL}, - {"0000110F-0000-1000-8000-00805F9B34FB", "VideoConferencing", NULL}, - {"00001110-0000-1000-8000-00805F9B34FB", "Intercom", NULL}, - {"00001111-0000-1000-8000-00805F9B34FB", "Fax", NULL}, - {"00001112-0000-1000-8000-00805F9B34FB", "HeadsetAudioGateway", NULL}, - {"00001113-0000-1000-8000-00805F9B34FB", "WAP", NULL}, - {"00001114-0000-1000-8000-00805F9B34FB", "WAPClient", NULL}, - {"00001115-0000-1000-8000-00805F9B34FB", "PANU", NULL}, - {"00001116-0000-1000-8000-00805F9B34FB", "NAP", NULL}, - {"00001117-0000-1000-8000-00805F9B34FB", "GN", NULL}, - {"00001118-0000-1000-8000-00805F9B34FB", "DirectPrinting", NULL}, - {"00001119-0000-1000-8000-00805F9B34FB", "ReferencePrinting", NULL}, - {"0000111A-0000-1000-8000-00805F9B34FB", "Imaging", NULL}, - {"0000111B-0000-1000-8000-00805F9B34FB", "ImagingResponder", NULL}, - {"0000111C-0000-1000-8000-00805F9B34FB", "ImagingAutomaticArchive", NULL}, - {"0000111D-0000-1000-8000-00805F9B34FB", "ImagingReferenceObjects", NULL}, - {"0000111E-0000-1000-8000-00805F9B34FB", "Handsfree", NULL}, - {"0000111F-0000-1000-8000-00805F9B34FB", "HandsfreeAudioGateway", NULL}, - {"00001120-0000-1000-8000-00805F9B34FB", "DirectPrintingReferenceObjects", NULL}, - {"00001121-0000-1000-8000-00805F9B34FB", "ReflectedUI", NULL}, - {"00001122-0000-1000-8000-00805F9B34FB", "BasicPringing", NULL}, - {"00001123-0000-1000-8000-00805F9B34FB", "PrintingStatus", NULL}, - {"00001124-0000-1000-8000-00805F9B34FB", "HumanInterfaceDevice", "HID"}, - {"00001125-0000-1000-8000-00805F9B34FB", "HardcopyCableReplacement", NULL}, - {"00001126-0000-1000-8000-00805F9B34FB", "HCRPrint", NULL}, - {"00001127-0000-1000-8000-00805F9B34FB", "HCRScan", NULL}, - {"00001128-0000-1000-8000-00805F9B34FB", "CommonISDNAccess", NULL}, - {"00001129-0000-1000-8000-00805F9B34FB", "VideoConferencingGW", NULL}, - {"0000112A-0000-1000-8000-00805F9B34FB", "UDIMT", NULL}, - {"0000112B-0000-1000-8000-00805F9B34FB", "UDITA", NULL}, - {"0000112C-0000-1000-8000-00805F9B34FB", "AudioVideo", NULL}, - {"00001200-0000-1000-8000-00805F9B34FB", "PnPInformation", NULL}, - {"00001201-0000-1000-8000-00805F9B34FB", "GenericNetworking", NULL}, - {"00001202-0000-1000-8000-00805F9B34FB", "GenericFileTransfer", NULL}, - {"00001203-0000-1000-8000-00805F9B34FB", "GenericAudio", NULL}, - {"00001204-0000-1000-8000-00805F9B34FB", "GenericTelephony", NULL}, - {"00001205-0000-1000-8000-00805F9B34FB", "UPnP", NULL}, - {"00001206-0000-1000-8000-00805F9B34FB", "UPnPIp", NULL}, - {"00001300-0000-1000-8000-00805F9B34FB", "ESdpUPnPIpPan", NULL}, - {"00001301-0000-1000-8000-00805F9B34FB", "ESdpUPnPIpLap", NULL}, - {"00001302-0000-1000-8000-00805F9B34FB", "EdpUPnpIpL2CAP", NULL}, - - // Custom: - {"0000112F-0000-1000-8000-00805F9B34FB", "PhoneBookAccess", NULL}, - {"831C4071-7BC8-4A9C-A01C-15DF25A4ADBC", "ActiveSync", NULL}, + {"00001000-0000-1000-8000-00805F9B34FB", "ServiceDiscoveryServer", NULL}, + {"00001001-0000-1000-8000-00805F9B34FB", "BrowseGroupDescriptor", NULL}, + {"00001002-0000-1000-8000-00805F9B34FB", "PublicBrowseGroup", NULL}, + {"00001101-0000-1000-8000-00805F9B34FB", "SerialPort", "Serial"}, + {"00001102-0000-1000-8000-00805F9B34FB", "LANAccessUsingPPP", NULL}, + {"00001103-0000-1000-8000-00805F9B34FB", "DialupNetworking", "DUN"}, + {"00001104-0000-1000-8000-00805F9B34FB", "IrMCSync", NULL}, + {"00001105-0000-1000-8000-00805F9B34FB", "OBEXObjectPush", NULL}, + {"00001106-0000-1000-8000-00805F9B34FB", "OBEXFileTransfer", NULL}, + {"00001107-0000-1000-8000-00805F9B34FB", "IrMCSyncCommand", NULL}, + {"00001108-0000-1000-8000-00805F9B34FB", "Headset", NULL}, + {"00001109-0000-1000-8000-00805F9B34FB", "CordlessTelephony", NULL}, + {"0000110A-0000-1000-8000-00805F9B34FB", "AudioSource", NULL}, + {"0000110B-0000-1000-8000-00805F9B34FB", "AudioSink", NULL}, + {"0000110C-0000-1000-8000-00805F9B34FB", "AVRemoteControlTarget", NULL}, + {"0000110D-0000-1000-8000-00805F9B34FB", "AdvancedAudioDistribution", "A2DP"}, + {"0000110E-0000-1000-8000-00805F9B34FB", "AVRemoteControl", NULL}, + {"0000110F-0000-1000-8000-00805F9B34FB", "VideoConferencing", NULL}, + {"00001110-0000-1000-8000-00805F9B34FB", "Intercom", NULL}, + {"00001111-0000-1000-8000-00805F9B34FB", "Fax", NULL}, + {"00001112-0000-1000-8000-00805F9B34FB", "HeadsetAudioGateway", NULL}, + {"00001113-0000-1000-8000-00805F9B34FB", "WAP", NULL}, + {"00001114-0000-1000-8000-00805F9B34FB", "WAPClient", NULL}, + {"00001115-0000-1000-8000-00805F9B34FB", "PANU", NULL}, + {"00001116-0000-1000-8000-00805F9B34FB", "NAP", NULL}, + {"00001117-0000-1000-8000-00805F9B34FB", "GN", NULL}, + {"00001118-0000-1000-8000-00805F9B34FB", "DirectPrinting", NULL}, + {"00001119-0000-1000-8000-00805F9B34FB", "ReferencePrinting", NULL}, + {"0000111A-0000-1000-8000-00805F9B34FB", "Imaging", NULL}, + {"0000111B-0000-1000-8000-00805F9B34FB", "ImagingResponder", NULL}, + {"0000111C-0000-1000-8000-00805F9B34FB", "ImagingAutomaticArchive", NULL}, + {"0000111D-0000-1000-8000-00805F9B34FB", "ImagingReferenceObjects", NULL}, + {"0000111E-0000-1000-8000-00805F9B34FB", "Handsfree", NULL}, + {"0000111F-0000-1000-8000-00805F9B34FB", "HandsfreeAudioGateway", NULL}, + {"00001120-0000-1000-8000-00805F9B34FB", "DirectPrintingReferenceObjects", NULL}, + {"00001121-0000-1000-8000-00805F9B34FB", "ReflectedUI", NULL}, + {"00001122-0000-1000-8000-00805F9B34FB", "BasicPringing", NULL}, + {"00001123-0000-1000-8000-00805F9B34FB", "PrintingStatus", NULL}, + {"00001124-0000-1000-8000-00805F9B34FB", "HumanInterfaceDevice", "HID"}, + {"00001125-0000-1000-8000-00805F9B34FB", "HardcopyCableReplacement", NULL}, + {"00001126-0000-1000-8000-00805F9B34FB", "HCRPrint", NULL}, + {"00001127-0000-1000-8000-00805F9B34FB", "HCRScan", NULL}, + {"00001128-0000-1000-8000-00805F9B34FB", "CommonISDNAccess", NULL}, + {"00001129-0000-1000-8000-00805F9B34FB", "VideoConferencingGW", NULL}, + {"0000112A-0000-1000-8000-00805F9B34FB", "UDIMT", NULL}, + {"0000112B-0000-1000-8000-00805F9B34FB", "UDITA", NULL}, + {"0000112C-0000-1000-8000-00805F9B34FB", "AudioVideo", NULL}, + {"00001200-0000-1000-8000-00805F9B34FB", "PnPInformation", NULL}, + {"00001201-0000-1000-8000-00805F9B34FB", "GenericNetworking", NULL}, + {"00001202-0000-1000-8000-00805F9B34FB", "GenericFileTransfer", NULL}, + {"00001203-0000-1000-8000-00805F9B34FB", "GenericAudio", NULL}, + {"00001204-0000-1000-8000-00805F9B34FB", "GenericTelephony", NULL}, + {"00001205-0000-1000-8000-00805F9B34FB", "UPnP", NULL}, + {"00001206-0000-1000-8000-00805F9B34FB", "UPnPIp", NULL}, + {"00001300-0000-1000-8000-00805F9B34FB", "ESdpUPnPIpPan", NULL}, + {"00001301-0000-1000-8000-00805F9B34FB", "ESdpUPnPIpLap", NULL}, + {"00001302-0000-1000-8000-00805F9B34FB", "EdpUPnpIpL2CAP", NULL}, + + // Custom: + {"0000112F-0000-1000-8000-00805F9B34FB", "PhoneBookAccess", NULL}, + {"831C4071-7BC8-4A9C-A01C-15DF25A4ADBC", "ActiveSync", NULL}, }; #define UUID_NAME_LOOKUP_TABLE_SIZE \ @@ -113,232 +114,346 @@ static uuid_name_lookup_table_t uuid_name_lookup_table[] = { const gchar *uuid2name(const gchar *uuid) { - if (uuid == NULL || strlen(uuid) == 0) - return NULL; + if (uuid == NULL || strlen(uuid) == 0) + return NULL; - for (int i = 0; i < UUID_NAME_LOOKUP_TABLE_SIZE; i++) { - if (g_ascii_strcasecmp(uuid_name_lookup_table[i].uuid, uuid) == 0) - return uuid_name_lookup_table[i].name; - } + for (int i = 0; i < UUID_NAME_LOOKUP_TABLE_SIZE; i++) + { + if (g_ascii_strcasecmp(uuid_name_lookup_table[i].uuid, uuid) == 0) + return uuid_name_lookup_table[i].name; + } - return uuid; + return uuid; } const gchar *name2uuid(const gchar *name) { - if (name == NULL || strlen(name) == 0) - return NULL; - - for (int i = 0; i < UUID_NAME_LOOKUP_TABLE_SIZE; i++) { - if ( - g_ascii_strcasecmp(uuid_name_lookup_table[i].name, name) == 0 || - (uuid_name_lookup_table[i].alt_name && g_ascii_strcasecmp(uuid_name_lookup_table[i].alt_name, name) == 0) - ) - return uuid_name_lookup_table[i].uuid; - } - - return name; + if (name == NULL || strlen(name) == 0) + return NULL; + + for (int i = 0; i < UUID_NAME_LOOKUP_TABLE_SIZE; i++) + { + if ( + g_ascii_strcasecmp(uuid_name_lookup_table[i].name, name) == 0 || + (uuid_name_lookup_table[i].alt_name && g_ascii_strcasecmp(uuid_name_lookup_table[i].alt_name, name) == 0) + ) + return uuid_name_lookup_table[i].uuid; + } + + return name; } int xtoi(const gchar *str) { - int i = 0; - sscanf(str, "0x%x", &i); - return i; + int i = 0; + sscanf(str, "0x%x", &i); + return i; } Adapter *find_adapter(const gchar *name, GError **error) { - gchar *adapter_path = NULL; - Adapter *adapter = NULL; - - Manager *manager = g_object_new(MANAGER_TYPE, NULL); - - // If name is null or empty - return default adapter - if (name == NULL || strlen(name) == 0) { - adapter_path = manager_default_adapter(manager, error); - if (adapter_path) { - adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL); - } - } else { - // Try to find by id - adapter_path = manager_find_adapter(manager, name, error); - - // Found - if (adapter_path) { - adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL); - } else { - // Try to find by name - const GPtrArray *adapters_list = manager_get_adapters(manager); - g_assert(adapters_list != NULL); - for (int i = 0; i < adapters_list->len; i++) { - adapter_path = g_ptr_array_index(adapters_list, i); - adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL); - adapter_path = NULL; - - if (g_strcmp0(name, adapter_get_name(adapter)) == 0) { - if (error) { - g_error_free(*error); - *error = NULL; - } - break; - } - - g_object_unref(adapter); - adapter = NULL; - } - } - } - - g_object_unref(manager); - if (adapter_path) g_free(adapter_path); - - return adapter; + gchar *adapter_path = NULL; + Adapter *adapter = NULL; + + Manager *manager = g_object_new(MANAGER_TYPE, NULL); + + // If name is null or empty - return default adapter + if (name == NULL || strlen(name) == 0) + { + adapter_path = (gchar *) manager_default_adapter(manager, error); + if (adapter_path) + { + // adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL); + adapter = adapter_new(adapter_path); + } + } + else + { + // Try to find by id + adapter_path = (gchar *) manager_find_adapter(manager, name, error); + + // Found + if (adapter_path) + { + // adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL); + adapter = adapter_new(adapter_path); + } + else + { + // Try to find by name + const GPtrArray *adapters_list = manager_get_adapters(manager); + g_assert(adapters_list != NULL); + for (int i = 0; i < adapters_list->len; i++) + { + adapter_path = g_ptr_array_index(adapters_list, i); + // adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL); + adapter = adapter_new(adapter_path); + adapter_path = NULL; + + if (g_strcmp0(name, adapter_get_name(adapter, error)) == 0) + { + if (error) + { + g_error_free(*error); + *error = NULL; + } + break; + } + + g_object_unref(adapter); + adapter = NULL; + } + } + } + + g_object_unref(manager); + if (adapter_path) g_free(adapter_path); + + return adapter; } Device *find_device(Adapter *adapter, const gchar *name, GError **error) { - g_assert(adapter != NULL && ADAPTER_IS(adapter)); - g_assert(name != NULL && strlen(name) > 0); - - gchar *device_path = NULL; - Device *device = NULL; - - // Try to find by MAC - device_path = adapter_find_device(adapter, name, error); - - // Found - if (device_path) { - device = g_object_new(DEVICE_TYPE, "DBusObjectPath", device_path, NULL); - } else { - // Try to find by name - const GPtrArray *devices_list = adapter_get_devices(adapter); - g_assert(devices_list != NULL); - for (int i = 0; i < devices_list->len; i++) { - device_path = g_ptr_array_index(devices_list, i); - device = g_object_new(DEVICE_TYPE, "DBusObjectPath", device_path, NULL); - device_path = NULL; - - if (g_strcmp0(name, device_get_name(device)) == 0 || g_strcmp0(name, device_get_alias(device)) == 0) { - if (error) { - g_error_free(*error); - *error = NULL; - } - break; - } - - g_object_unref(device); - device = NULL; - } - } - - if (device_path) g_free(device_path); - - return device; + g_assert(adapter != NULL && ADAPTER_IS(adapter)); + g_assert(name != NULL && strlen(name) > 0); + + Device *device = NULL; + + Manager *manager = g_object_new(MANAGER_TYPE, NULL); + + GVariant *objects = manager_get_managed_objects(manager, error); + + g_clear_object(&manager); + + if(!objects) + { + return NULL; + } + + const gchar *object_path; + GVariant *ifaces_and_properties; + GVariantIter i; + + g_variant_iter_init(&i, objects); + while (g_variant_iter_next(&i, "{&o@a{sa{sv}}}", &object_path, &ifaces_and_properties) && device == NULL) + { + GVariant *properties = NULL; + + if(g_variant_lookup(ifaces_and_properties, DEVICE_DBUS_INTERFACE, "@a{sv}", &properties)) + { + gchar *adapter_path = NULL; + if(g_variant_lookup(properties, "Adapter", "o", &adapter_path)) + { + if(g_strcmp0(adapter_path, adapter_get_dbus_object_path(adapter)) == 0) + { + // Now check if this is the device we are looking for. + + // Try to find by MAC + gchar *address = NULL; + + if(g_variant_lookup(properties, "Address", "s", &address)) + { + if(g_strcmp0(g_ascii_strdown(address, -1), g_ascii_strdown(name, -1)) == 0) + { + device = device_new(object_path); + } + g_free(address); + } + + // Try to find by name or alias + if(!device) + { + gchar *device_name = NULL; + gchar *device_alias = NULL; + g_variant_lookup(properties, "Name", "s", &device_name); + g_variant_lookup(properties, "Alias", "s", &device_alias); + + if (g_strcmp0(name, device_name) == 0 || g_strcmp0(name, device_alias) == 0) { + device = device_new(object_path); + } + + g_free(device_alias); + g_free(device_name); + } + } + g_free(adapter_path); + } + g_variant_unref(properties); + } + g_variant_unref(ifaces_and_properties); + } + g_variant_unref(objects); + + return device; } gboolean intf_supported(const gchar *dbus_service_name, const gchar *dbus_object_path, const gchar *intf_name) { - g_assert(dbus_service_name != NULL && strlen(dbus_service_name) > 0); - g_assert(dbus_object_path != NULL && strlen(dbus_object_path) > 0); - g_assert(intf_name != NULL && strlen(intf_name) > 0); - - gboolean supported = FALSE; - DBusGConnection *conn = NULL; - - if (g_strcmp0(dbus_service_name, BLUEZ_DBUS_NAME) == 0) { - conn = system_conn; -#ifdef OBEX_SUPPORT - } else if (g_strcmp0(dbus_service_name, OBEXS_DBUS_NAME) == 0 || g_strcmp0(dbus_service_name, OBEXC_DBUS_NAME) == 0) { - conn = session_conn; -#endif - } else { - return FALSE; - } - g_assert(conn != NULL); - - gchar *check_intf_regex_str = g_strconcat("<interface name=\"", intf_name, "\">", NULL); - - /* Getting introspection XML */ - DBusGProxy *introspection_g_proxy = dbus_g_proxy_new_for_name(conn, dbus_service_name, dbus_object_path, "org.freedesktop.DBus.Introspectable"); - gchar *introspection_xml = NULL; - GError *error = NULL; - if (!dbus_g_proxy_call(introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &introspection_xml, G_TYPE_INVALID)) { + g_assert(dbus_service_name != NULL && strlen(dbus_service_name) > 0); + g_assert(dbus_object_path != NULL && strlen(dbus_object_path) > 0); + g_assert(intf_name != NULL && strlen(intf_name) > 0); + + gboolean supported = FALSE; + GDBusConnection *conn = NULL; + + if (g_strcmp0(dbus_service_name, BLUEZ_DBUS_SERVICE_NAME) == 0) + { + conn = system_conn; + } + else if (g_strcmp0(dbus_service_name, BLUEZ_OBEX_DBUS_SERVICE_NAME) == 0) + { + conn = session_conn; + } + else + { + return FALSE; + } + g_assert(conn != NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", intf_name, "\">", NULL); + + /* Getting introspection XML */ + GError *error = NULL; + GDBusProxy *introspection_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dbus_service_name, dbus_object_path, "org.freedesktop.DBus.Introspectable", NULL, &error); + g_assert(introspection_proxy != NULL); + GVariant *introspection_ret = g_dbus_proxy_call_sync(introspection_proxy, "Introspect", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + gchar *introspection_xml = NULL; + if (!introspection_ret) + { #if 0 - g_critical("%s", error->message); + g_critical("%s", error->message); #else - g_error_free(error); - error = NULL; - introspection_xml = g_strdup("null"); + g_error_free(error); + error = NULL; + introspection_xml = g_strdup("null"); #endif - } - g_assert(error == NULL); - - if (g_regex_match_simple(check_intf_regex_str, introspection_xml, 0, 0)) { - supported = TRUE; - } - - g_free(check_intf_regex_str); - g_free(introspection_xml); - g_object_unref(introspection_g_proxy); - - return supported; + } + else + { + introspection_xml = (gchar *) g_variant_get_string(g_variant_get_child_value(introspection_ret, 0), NULL); + } + g_assert(error == NULL); + + if (g_regex_match_simple(check_intf_regex_str, introspection_xml, 0, 0)) + { + supported = TRUE; + } + + g_free(check_intf_regex_str); + g_free(introspection_xml); + if(introspection_ret) + g_variant_unref(introspection_ret); + g_object_unref(introspection_proxy); + + return supported; } gboolean is_file(const gchar *filename, GError **error) { - g_assert(filename != NULL && strlen(filename) > 0); - - struct stat buf; - if (stat(filename, &buf) != 0) { - if (error) { - *error = g_error_new(g_quark_from_string("bluez-tools"), 1, "%s: %s", g_strdup(filename), strerror(errno)); - } - return FALSE; - } - - if (!S_ISREG(buf.st_mode)) { - if (error) { - *error = g_error_new(g_quark_from_string("bluez-tools"), 2, "%s: Invalid file", g_strdup(filename)); - } - return FALSE; - } - - return TRUE; + g_assert(filename != NULL && strlen(filename) > 0); + + struct stat buf; + if (stat(filename, &buf) != 0) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 1, "%s: %s", g_strdup(filename), strerror(errno)); + } + return FALSE; + } + + if (!S_ISREG(buf.st_mode)) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 2, "%s: Invalid file", g_strdup(filename)); + } + return FALSE; + } + + return TRUE; } gboolean is_dir(const gchar *dirname, GError **error) { - g_assert(dirname != NULL && strlen(dirname) > 0); - - struct stat buf; - if (stat(dirname, &buf) != 0) { - if (error) { - *error = g_error_new(g_quark_from_string("bluez-tools"), 1, "%s: %s", g_strdup(dirname), strerror(errno)); - } - return FALSE; - } - - if (!S_ISDIR(buf.st_mode)) { - if (error) { - *error = g_error_new(g_quark_from_string("bluez-tools"), 2, "%s: Invalid directory", g_strdup(dirname)); - } - return FALSE; - } - - return TRUE; + g_assert(dirname != NULL && strlen(dirname) > 0); + + struct stat buf; + if (stat(dirname, &buf) != 0) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 1, "%s: %s", g_strdup(dirname), strerror(errno)); + } + return FALSE; + } + + if (!S_ISDIR(buf.st_mode)) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 2, "%s: Invalid directory", g_strdup(dirname)); + } + return FALSE; + } + + return TRUE; +} + +gboolean read_access(const gchar *path, GError **error) +{ + if(g_access(path, F_OK) != 0) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 3, "%s: No such file or directory", g_strdup(path)); + } + return FALSE; + } + if(g_access(path, R_OK | F_OK) != 0) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 4, "%s: Read permission denied", g_strdup(path)); + } + return FALSE; + } + + return TRUE; +} + +gboolean write_access(const gchar *path, GError **error) +{ + if(g_access(path, F_OK) != 0) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 3, "%s: No such file or directory", g_strdup(path)); + } + return FALSE; + } + if(g_access(path, W_OK | F_OK) != 0) + { + if (error) + { + *error = g_error_new(g_quark_from_string("bluez-tools"), 5, "%s: Write permission denied", g_strdup(path)); + } + return FALSE; + } + + return TRUE; } gchar *get_absolute_path(const gchar *path) { - if (g_path_is_absolute(path)) { - return g_strdup(path); - } + if (g_path_is_absolute(path)) + { + return g_strdup(path); + } - gchar *current_dir = g_get_current_dir(); - gchar *abs_path = g_build_filename(current_dir, path, NULL); - g_free(current_dir); + gchar *current_dir = g_get_current_dir(); + gchar *abs_path = g_build_filename(current_dir, path, NULL); + g_free(current_dir); - return abs_path; + return abs_path; } - diff --git a/src/lib/helpers.h b/src/lib/helpers.h index eed1e6c..344410e 100644 --- a/src/lib/helpers.h +++ b/src/lib/helpers.h @@ -24,14 +24,11 @@ #ifndef __HELPERS_H #define __HELPERS_H -#include <stdio.h> - #include <glib.h> +#include <stdio.h> +#include <string.h> #include "bluez-api.h" -#ifdef OBEX_SUPPORT -#include "obexd-api.h" -#endif /* DBus helpers */ gboolean intf_supported(const gchar *dbus_service_name, const gchar *dbus_object_path, const gchar *intf_name); @@ -43,7 +40,7 @@ Device *find_device(Adapter *adapter, const gchar *name, GError **error); /* Others helpers */ #define exit_if_error(error) G_STMT_START{ \ if (error) { \ - g_printerr("%s: %s\n", (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION && dbus_g_error_get_name(error) != NULL && strlen(dbus_g_error_get_name(error)) ? dbus_g_error_get_name(error) : "Error"), error->message); \ + g_printerr("%s: %s\n", (error->domain == G_DBUS_ERROR && g_dbus_error_get_remote_error(error) != NULL && strlen(g_dbus_error_get_remote_error(error)) ? g_dbus_error_get_remote_error(error) : "Error"), error->message); \ exit(EXIT_FAILURE); \ }; }G_STMT_END @@ -57,7 +54,8 @@ const gchar *name2uuid(const gchar *name); /* FS helpers */ gboolean is_file(const gchar *filename, GError **error); gboolean is_dir(const gchar *dirname, GError **error); +gboolean read_access(const gchar *path, GError **error); +gboolean write_access(const gchar *path, GError **error); gchar *get_absolute_path(const gchar *path); #endif /* __HELPERS_H */ - diff --git a/src/lib/manager.c b/src/lib/manager.c new file mode 100644 index 0000000..5286a3a --- /dev/null +++ b/src/lib/manager.c @@ -0,0 +1,276 @@ +#include <gio/gio.h> +#include "bluez-api.h" +#include "dbus-common.h" +#include "manager.h" + +struct _ManagerPrivate +{ + GDBusProxy *proxy; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(Manager, manager, G_TYPE_OBJECT) + +static void manager_dispose (GObject *gobject) +{ + Manager *self = MANAGER (gobject); + + /* In dispose(), you are supposed to free all types referenced from this + * object which might themselves hold a reference to self. Generally, + * the most simple solution is to unref all members on which you own a + * reference. + */ + + /* dispose() might be called multiple times, so we must guard against + * calling g_object_unref() on an invalid GObject by setting the member + * NULL; g_clear_object() does this for us, atomically. + */ + // g_clear_object (&self->priv->an_object); + g_clear_object (&self->priv->proxy); + + + /* Always chain up to the parent class; there is no need to check if + * the parent class implements the dispose() virtual function: it is + * always guaranteed to do so + */ + G_OBJECT_CLASS (manager_parent_class)->dispose (gobject); +} + +static void manager_finalize (GObject *gobject) +{ + Manager *self = MANAGER(gobject); + + // g_free(self->priv->a_string); + + /* Always chain up to the parent class; as with dispose(), finalize() + * is guaranteed to exist on the parent's class virtual function table + */ + G_OBJECT_CLASS (manager_parent_class)->finalize (gobject); +} + +static void manager_class_init(ManagerClass *klass) +{ +} + +static void manager_init(Manager *self) +{ + self->priv = manager_get_instance_private(self); + GError *error = NULL; + + g_assert(system_conn != NULL); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, BLUEZ_DBUS_SERVICE_NAME, MANAGER_DBUS_PATH, MANAGER_DBUS_INTERFACE, NULL, &error); + + if (self->priv->proxy == NULL) + { + g_critical("%s", error->message); + } + g_assert(error == NULL); +} + +Manager *manager_new() +{ + return g_object_new(MANAGER_TYPE, NULL); +} + +GVariant *manager_get_managed_objects(Manager *self, GError **error) +{ + g_assert(MANAGER_IS(self)); + + GVariant *retVal = NULL; + retVal = g_dbus_proxy_call_sync(self->priv->proxy, "GetManagedObjects", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + + if (retVal != NULL) + retVal = g_variant_get_child_value(retVal, 0); + + return retVal; +} + +const gchar *manager_default_adapter(Manager *self, GError **error) +{ + g_assert(MANAGER_IS(self)); + + GVariant *objects = NULL; + objects = manager_get_managed_objects(self, error); + if (objects == NULL) + return NULL; + + const gchar *object_path; + GVariant *ifaces_and_properties; + GVariantIter i; + + g_variant_iter_init(&i, objects); + while (g_variant_iter_next(&i, "{&o@a{sa{sv}}}", &object_path, &ifaces_and_properties)) + { + const gchar *interface_name; + GVariant *properties; + GVariantIter ii; + g_variant_iter_init(&ii, ifaces_and_properties); + while (g_variant_iter_next(&ii, "{&s@a{sv}}", &interface_name, &properties)) + { + if (g_strstr_len(g_ascii_strdown(interface_name, -1), -1, "adapter")) + { + const gchar *retVal = g_strdup(object_path); + g_variant_unref(properties); + g_variant_unref(ifaces_and_properties); + g_variant_unref(objects); + return retVal; + } + g_variant_unref(properties); + } + g_variant_unref(ifaces_and_properties); + } + g_variant_unref(objects); + + return NULL; +} + +const gchar *manager_find_adapter(Manager *self, const gchar *pattern, GError **error) +{ + g_assert(MANAGER_IS(self)); + + GVariant *objects = NULL; + objects = manager_get_managed_objects(self, error); + if (objects == NULL) + return NULL; + + const gchar *object_path; + GVariant *ifaces_and_properties; + GVariantIter i; + + g_variant_iter_init(&i, objects); + while (g_variant_iter_next(&i, "{&o@a{sa{sv}}}", &object_path, &ifaces_and_properties)) + { + const gchar *interface_name; + GVariant *properties; + GVariantIter ii; + g_variant_iter_init(&ii, ifaces_and_properties); + while (g_variant_iter_next(&ii, "{&s@a{sv}}", &interface_name, &properties)) + { + if (g_strstr_len(g_ascii_strdown(interface_name, -1), -1, "adapter")) + { + const gchar *object_base_name = g_path_get_basename(object_path); + if (g_strstr_len(g_ascii_strdown(object_base_name, -1), -1, g_ascii_strdown(pattern, -1))) + { + const gchar *retVal = g_strdup(object_path); + g_variant_unref(properties); + g_variant_unref(ifaces_and_properties); + g_variant_unref(objects); + return retVal; + } + const gchar *address = g_variant_get_string(g_variant_lookup_value(properties, "Address", NULL), NULL); + if (g_strstr_len(g_ascii_strdown(address, -1), -1, g_ascii_strdown(pattern, -1))) + { + gchar *retVal = g_strdup(object_path); + g_variant_unref(properties); + g_variant_unref(ifaces_and_properties); + g_variant_unref(objects); + return retVal; + } + } + g_variant_unref(properties); + } + g_variant_unref(ifaces_and_properties); + } + g_variant_unref(objects); + + return NULL; +} + +GPtrArray *manager_get_adapters(Manager *self) +{ + g_assert(MANAGER_IS(self)); + + GVariant *objects = NULL; + GError *error = NULL; + objects = manager_get_managed_objects(self, &error); + if (objects == NULL) + { + g_critical("%s", error->message); + g_error_free(error); + return NULL; + } + + GPtrArray *adapter_array = g_ptr_array_new(); + + const gchar *object_path; + GVariant *ifaces_and_properties; + GVariantIter i; + + g_variant_iter_init(&i, objects); + while (g_variant_iter_next(&i, "{&o@a{sa{sv}}}", &object_path, &ifaces_and_properties)) + { + const gchar *interface_name; + GVariant *properties; + GVariantIter ii; + g_variant_iter_init(&ii, ifaces_and_properties); + while (g_variant_iter_next(&ii, "{&s@a{sv}}", &interface_name, &properties)) + { + if (g_strstr_len(g_ascii_strdown(interface_name, -1), -1, "adapter")) + g_ptr_array_add(adapter_array, (gpointer) g_strdup(object_path)); + g_variant_unref(properties); + } + g_variant_unref(ifaces_and_properties); + } + g_variant_unref(objects); + + return adapter_array; +} + +const gchar **manager_get_devices(Manager *self, const gchar *adapter_pattern) +{ + g_assert(MANAGER_IS(self)); + + GVariant *objects = NULL; + GError *error = NULL; + objects = manager_get_managed_objects(self, &error); + if (objects == NULL) + { + g_critical("%s", error->message); + g_error_free(error); + return NULL; + } + + GRegex *adapter_regex = g_regex_new(adapter_pattern, 0, 0, &error); + if (adapter_regex == NULL) + { + g_critical("%s", error->message); + g_error_free(error); + } + + GPtrArray *device_array = g_ptr_array_new(); + + const gchar *object_path; + GVariant *ifaces_and_properties; + GVariantIter i; + + g_variant_iter_init(&i, objects); + while (g_variant_iter_next(&i, "{&o@a{sa{sv}}}", &object_path, &ifaces_and_properties)) + { + const gchar *interface_name; + GVariant *properties; + GVariantIter ii; + g_variant_iter_init(&ii, ifaces_and_properties); + while (g_variant_iter_next(&ii, "{&s@a{sv}}", &interface_name, &properties)) + { + if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) + { + const gchar *adapter_prop = g_variant_get_string(g_variant_lookup_value(properties, "Adapter", G_VARIANT_TYPE_OBJECT_PATH), NULL); + if(g_regex_match(adapter_regex, adapter_prop, 0, NULL)) + g_ptr_array_add(device_array, (gpointer) g_strdup(object_path)); + } + g_variant_unref(properties); + } + g_variant_unref(ifaces_and_properties); + } + g_variant_unref(objects); + + g_regex_unref(adapter_regex); + + if(device_array->len > 0) + { + // Top it off with a NULL pointer + g_ptr_array_add(device_array, (gpointer) NULL); + return (const gchar**) g_ptr_array_free(device_array, FALSE); + } + else + return NULL; +}
\ No newline at end of file diff --git a/src/lib/manager.h b/src/lib/manager.h new file mode 100644 index 0000000..0c9e052 --- /dev/null +++ b/src/lib/manager.h @@ -0,0 +1,67 @@ +#ifndef MANAGER_H +#define MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + /* + * Potentially, include other headers on which this header depends. + */ + + /* + * 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)) + +#define MANAGER_DBUS_PATH "/" +#define MANAGER_DBUS_INTERFACE "org.freedesktop.DBus.ObjectManager" + + typedef struct _Manager Manager; + typedef struct _ManagerPrivate ManagerPrivate; + typedef struct _ManagerClass ManagerClass; + + struct _Manager { + /* Parent instance structure */ + GObject parent_instance; + + /* instance members */ + ManagerPrivate *priv; + }; + + struct _ManagerClass { + /* Parent class structure */ + GObjectClass parent_class; + + /* class members */ + }; + + /* used by MANAGER_TYPE */ + GType manager_get_type(void); + + /* + * Constructor + */ + Manager *manager_new(); + + /* + * Method definitions. + */ + GVariant *manager_get_managed_objects(Manager *self, GError **error); + const gchar *manager_default_adapter(Manager *self, GError **error); + const gchar *manager_find_adapter(Manager *self, const gchar *pattern, GError **error); + GPtrArray *manager_get_adapters(Manager *self); + const gchar **manager_get_devices(Manager *self, const gchar *adapter_pattern); + +#ifdef __cplusplus +} +#endif + +#endif /* MANAGER_H */ + diff --git a/src/lib/marshallers.c b/src/lib/marshallers.c deleted file mode 100644 index c88186e..0000000 --- a/src/lib/marshallers.c +++ /dev/null @@ -1,588 +0,0 @@ - -#include <glib-object.h> - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_char (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:STRING,BOXED (lib/marshallers.list:2) */ -void -g_cclosure_bt_marshal_VOID__STRING_BOXED (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__STRING_BOXED) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_VOID__STRING_BOXED callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__STRING_BOXED) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_boxed (param_values + 2), - data2); -} - -/* BOOLEAN:POINTER (lib/marshallers.list:5) */ -void -g_cclosure_bt_marshal_BOOLEAN__POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1, - gpointer arg_1, - gpointer data2); - register GMarshalFunc_BOOLEAN__POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 2); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:6) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_POINTER_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_pointer (param_values + 2), - g_marshal_value_peek_pointer (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:7) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER) (gpointer data1, - gpointer arg_1, - guint arg_2, - guchar arg_3, - gpointer arg_4, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 5); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - g_marshal_value_peek_uchar (param_values + 3), - g_marshal_value_peek_pointer (param_values + 4), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:8) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_UINT_POINTER) (gpointer data1, - gpointer arg_1, - guint arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_UINT_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_UINT_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - g_marshal_value_peek_pointer (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:9) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_string (param_values + 2), - g_marshal_value_peek_pointer (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:STRING,POINTER (lib/marshallers.list:10) */ -void -g_cclosure_bt_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_BOOLEAN__STRING_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__STRING_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_pointer (param_values + 2), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* VOID:INT,INT (lib/marshallers.list:13) */ -void -g_cclosure_bt_marshal_VOID__INT_INT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, - gint arg_1, - gint arg_2, - gpointer data2); - register GMarshalFunc_VOID__INT_INT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_int (param_values + 1), - g_marshal_value_peek_int (param_values + 2), - data2); -} - -/* VOID:STRING,BOOLEAN (lib/marshallers.list:16) */ -void -g_cclosure_bt_marshal_VOID__STRING_BOOLEAN (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer data1, - gpointer arg_1, - gboolean arg_2, - gpointer data2); - register GMarshalFunc_VOID__STRING_BOOLEAN callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__STRING_BOOLEAN) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_boolean (param_values + 2), - data2); -} - -/* VOID:BOXED,BOOLEAN (lib/marshallers.list:17) */ -void -g_cclosure_bt_marshal_VOID__BOXED_BOOLEAN (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__BOXED_BOOLEAN) (gpointer data1, - gpointer arg_1, - gboolean arg_2, - gpointer data2); - register GMarshalFunc_VOID__BOXED_BOOLEAN callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__BOXED_BOOLEAN) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_boolean (param_values + 2), - data2); -} - -/* BOOLEAN:BOXED,STRING,STRING,STRING,INT,INT,POINTER,POINTER (lib/marshallers.list:20) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer arg_4, - gint arg_5, - gint arg_6, - gpointer arg_7, - gpointer arg_8, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 9); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_string (param_values + 2), - g_marshal_value_peek_string (param_values + 3), - g_marshal_value_peek_string (param_values + 4), - g_marshal_value_peek_int (param_values + 5), - g_marshal_value_peek_int (param_values + 6), - g_marshal_value_peek_pointer (param_values + 7), - g_marshal_value_peek_pointer (param_values + 8), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,UINT64,POINTER (lib/marshallers.list:23) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT64_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_UINT64_POINTER) (gpointer data1, - gpointer arg_1, - guint64 arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_UINT64_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_UINT64_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_uint64 (param_values + 2), - g_marshal_value_peek_pointer (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,POINTER (lib/marshallers.list:24) */ -void -g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_BOOLEAN__BOXED_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_boxed (param_values + 1), - g_marshal_value_peek_pointer (param_values + 2), - data2); - - g_value_set_boolean (return_value, v_return); -} - diff --git a/src/lib/marshallers.h b/src/lib/marshallers.h deleted file mode 100644 index 510e605..0000000 --- a/src/lib/marshallers.h +++ /dev/null @@ -1,116 +0,0 @@ - -#ifndef __g_cclosure_bt_marshal_MARSHAL_H__ -#define __g_cclosure_bt_marshal_MARSHAL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -/* VOID:STRING,BOXED (lib/marshallers.list:2) */ -extern void g_cclosure_bt_marshal_VOID__STRING_BOXED (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:POINTER (lib/marshallers.list:5) */ -extern void g_cclosure_bt_marshal_BOOLEAN__POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:6) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:7) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:8) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:9) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:STRING,POINTER (lib/marshallers.list:10) */ -extern void g_cclosure_bt_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:INT,INT (lib/marshallers.list:13) */ -extern void g_cclosure_bt_marshal_VOID__INT_INT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:STRING,BOOLEAN (lib/marshallers.list:16) */ -extern void g_cclosure_bt_marshal_VOID__STRING_BOOLEAN (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:BOXED,BOOLEAN (lib/marshallers.list:17) */ -extern void g_cclosure_bt_marshal_VOID__BOXED_BOOLEAN (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,STRING,STRING,STRING,INT,INT,POINTER,POINTER (lib/marshallers.list:20) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,UINT64,POINTER (lib/marshallers.list:23) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT64_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,POINTER (lib/marshallers.list:24) */ -extern void g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - -#endif /* __g_cclosure_bt_marshal_MARSHAL_H__ */ - diff --git a/src/lib/marshallers.list b/src/lib/marshallers.list deleted file mode 100644 index 87edb09..0000000 --- a/src/lib/marshallers.list +++ /dev/null @@ -1,25 +0,0 @@ -# [bluez] -VOID:STRING,BOXED - -# Used by Agent -BOOLEAN:POINTER -BOOLEAN:BOXED,POINTER,POINTER -BOOLEAN:BOXED,UINT,UCHAR,POINTER -BOOLEAN:BOXED,UINT,POINTER -BOOLEAN:BOXED,STRING,POINTER -BOOLEAN:STRING,POINTER - -# [obexd] -VOID:INT,INT - -# equals -VOID:STRING,BOOLEAN -VOID:BOXED,BOOLEAN - -# Used by OBEXAgent -BOOLEAN:BOXED,STRING,STRING,STRING,INT,INT,POINTER,POINTER -#BOOLEAN:POINTER -#BOOLEAN:BOXED,POINTER,POINTER -BOOLEAN:BOXED,UINT64,POINTER -BOOLEAN:BOXED,POINTER -#BOOLEAN:BOXED,STRING,POINTER diff --git a/src/lib/obex_agent.c b/src/lib/obex_agent.c new file mode 100644 index 0000000..f835f04 --- /dev/null +++ b/src/lib/obex_agent.c @@ -0,0 +1,296 @@ +/* + * + * 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 <stdio.h> +#include <string.h> +#include <errno.h> + +#include "dbus-common.h" +#include "helpers.h" +#include "properties.h" + +#include "obex_agent.h" +#include "bluez/obex/obex_transfer.h" + +#define OBEX_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEX_AGENT_TYPE, ObexAgentPrivate)) + +struct _ObexAgentPrivate { + gchar *root_folder; + gchar *current_name; + guint registration_id; + void (*agent_released_callback)(ObexAgent *, gpointer); + gpointer user_data; + void (*agent_approved_callback)(ObexAgent *, const gchar *, const gchar *, const guint64, gpointer); + gpointer approved_user_data; +}; + +G_DEFINE_TYPE_WITH_PRIVATE(ObexAgent, obex_agent, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_ROOT_FOLDER, /* readwrite, construct only */ +}; + +static const gchar *_obex_agent_introspect_xml = "<node name=\"/org/blueztools/obex\">\n\t<interface name=\"org.bluez.obex.Agent1\">\n\t\t<method name=\"Release\">\n\t\t</method>\n\t\t<method name=\"AuthorizePush\">\n\t\t\t<arg name=\"transfer\" direction=\"in\" type=\"o\"/>\n\t\t\t<arg name=\"filepath\" direction=\"out\" type=\"s\"/>\n\t\t</method>\n\t\t<method name=\"Cancel\">\n\t\t</method>\n\t</interface>\n</node>\n"; + +/* Client API */ +static gboolean _update_progress = FALSE; + +static void _obex_agent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obex_agent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void _obex_agent_method_call_func(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data); +static void _obex_agent_g_destroy_notify(gpointer data); + +static void obex_agent_dispose(GObject *gobject) +{ + ObexAgent *self = OBEX_AGENT(gobject); + + if(self->priv->registration_id) + g_dbus_connection_unregister_object(session_conn, self->priv->registration_id); + /* Root folder free */ + g_free(self->priv->root_folder); + /* callback free */ + if(self->priv->agent_released_callback) + self->priv->agent_released_callback = NULL; + /* user data free */ + if(self->priv->user_data) + self->priv->user_data = NULL; + /* callback free */ + if(self->priv->agent_approved_callback) + self->priv->agent_approved_callback = NULL; + /* user data free */ + if(self->priv->approved_user_data) + self->priv->approved_user_data = NULL; + /* Chain up to the parent class */ + G_OBJECT_CLASS(obex_agent_parent_class)->dispose(gobject); +} + +static void obex_agent_finalize (GObject *gobject) +{ + ObexAgent *self = OBEX_AGENT(gobject); + G_OBJECT_CLASS(obex_agent_parent_class)->finalize(gobject); +} + +static void obex_agent_class_init(ObexAgentClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obex_agent_dispose; + + /* Properties registration */ + GParamSpec *pspec = NULL; + + gobject_class->get_property = _obex_agent_get_property; + gobject_class->set_property = _obex_agent_set_property; + + /* string RootFolder [readwrite, construct only] */ + pspec = g_param_spec_string("RootFolder", "root_folder", "Root folder location", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_ROOT_FOLDER, pspec); + + if (pspec) + g_param_spec_unref(pspec); +} + +static void obex_agent_init(ObexAgent *self) +{ + self->priv = obex_agent_get_instance_private(self); + g_assert(session_conn != NULL); + self->priv->registration_id = 0; + self->priv->root_folder = NULL; + self->priv->agent_released_callback = NULL; + self->priv->user_data = NULL; + self->priv->agent_approved_callback = NULL; + self->priv->approved_user_data = NULL; + + GError *error = NULL; + GDBusInterfaceVTable obex_agent_table; + memset(&obex_agent_table, 0x0, sizeof(obex_agent_table)); + + GDBusNodeInfo *obex_agent_node_info = g_dbus_node_info_new_for_xml(_obex_agent_introspect_xml, &error); + g_assert(error == NULL); + GDBusInterfaceInfo *obex_agent_interface_info = g_dbus_node_info_lookup_interface(obex_agent_node_info, OBEX_AGENT_DBUS_INTERFACE); + obex_agent_table.method_call = _obex_agent_method_call_func; + self->priv->registration_id = g_dbus_connection_register_object(session_conn, OBEX_AGENT_DBUS_PATH, obex_agent_interface_info, &obex_agent_table, self, _obex_agent_g_destroy_notify, &error); + g_assert(error == NULL); + g_assert(self->priv->registration_id != 0); + g_dbus_node_info_unref(obex_agent_node_info); +} + +static void _obex_agent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + ObexAgent *self = OBEX_AGENT(object); + + switch (property_id) { + case PROP_ROOT_FOLDER: + g_value_set_string(value, self->priv->root_folder); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obex_agent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + ObexAgent *self = OBEX_AGENT(object); + + switch (property_id) { + case PROP_ROOT_FOLDER: + self->priv->root_folder = g_value_dup_string(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* Constructor */ +ObexAgent *obex_agent_new(const gchar *root_folder) +{ + return g_object_new(OBEX_AGENT_TYPE, "RootFolder", root_folder, NULL); +} +/* Methods */ +static void _obex_agent_method_call_func(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) +{ + g_assert(user_data != NULL); + ObexAgent *self = user_data; + + if (g_strcmp0(method_name, "AuthorizePush") == 0) + { + const gchar *transfer = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL); + if (intf_supported(OBEX_TRANSFER_DBUS_SERVICE, transfer, OBEX_TRANSFER_DBUS_INTERFACE)) + { + ObexTransfer *transfer_t = obex_transfer_new(transfer); + g_print("[Transfer Request]\n"); + g_print(" Name: %s\n", obex_transfer_get_name(transfer_t, NULL)); + g_print(" Size: %llu bytes\n", obex_transfer_get_size(transfer_t, NULL)); + // Filename seems to be always NULL + // g_print(" Filename: %s\n", obex_transfer_get_filename(transfer_t, NULL)); + const gchar *filename = obex_transfer_get_name(transfer_t, NULL); + const guint64 size = obex_transfer_get_size(transfer_t, NULL); + g_object_unref(transfer_t); + + gchar yn[4] = {0,}; + g_print("Accept (yes/no)? "); + 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) + { + // IMPORTANT NOTE! + // OBEX CANNOT WRITE FILES OUTSIDE OF /home/<user>/.cache/obexd + // GVariant *ret = g_variant_new("(s)", g_build_filename(self->priv->root_folder, filename, NULL)); + // This will store the file in /home/<user>/.cache/obexd + GVariant *ret = g_variant_new("(s)", filename); + // g_print("invocation return value: %s\n", g_variant_print(ret, TRUE)); + + // Call the callback to handle the filename and size + if(self->priv->agent_approved_callback) + (*self->priv->agent_approved_callback)(self, transfer, filename, size, self->priv->approved_user_data); + + // Return string + g_dbus_method_invocation_return_value(invocation, ret); + return; + } + else + { + // Return error + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.obex.Error.Rejected", "File transfer rejected"); + return; + } + } + else + { + g_print("Error: Unknown transfer request\n"); + // Return error + g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.obex.Error.Rejected", "File transfer rejected"); + return; + } + } + else if (g_strcmp0(method_name, "Cancel") == 0) + { + g_print("Request cancelled\n"); + // Return void + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + else if (g_strcmp0(method_name, "Release") == 0) + { + if (_update_progress) + { + g_print("\n"); + _update_progress = FALSE; + } + + g_print("OBEXAgent released\n"); + + (*self->priv->agent_released_callback)(self, self->priv->user_data); + + // Return void + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } +} + +static void _obex_agent_g_destroy_notify(gpointer data) +{ + g_free(data); +} + +void obex_agent_set_release_callback(ObexAgent *self, ObexAgentReleasedCallback callback_function, gpointer user_data) +{ + g_assert(OBEX_AGENT_IS(self)); + self->priv->agent_released_callback = callback_function; + self->priv->user_data = user_data; +} + +void obex_agent_clear_release_callback(ObexAgent *self) +{ + g_assert(OBEX_AGENT_IS(self)); + self->priv->agent_released_callback = NULL; + self->priv->user_data = NULL; +} + +void obex_agent_set_approved_callback(ObexAgent *self, ObexAgentApprovedCallback callback_function, gpointer user_data) +{ + g_assert(OBEX_AGENT_IS(self)); + self->priv->agent_approved_callback = callback_function; + self->priv->approved_user_data = user_data; +} + +void obex_agent_clear_approved_callback(ObexAgent *self) +{ + g_assert(OBEX_AGENT_IS(self)); + self->priv->agent_approved_callback = NULL; + self->priv->approved_user_data = NULL; +}
\ No newline at end of file diff --git a/src/lib/obex_agent.h b/src/lib/obex_agent.h new file mode 100644 index 0000000..981dc46 --- /dev/null +++ b/src/lib/obex_agent.h @@ -0,0 +1,92 @@ +/* + * + * 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_H +#define __OBEX_AGENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> + +#define OBEX_AGENT_DBUS_SERVICE "org.blueztools" +#define OBEX_AGENT_DBUS_INTERFACE "org.bluez.obex.Agent1" +#define OBEX_AGENT_DBUS_PATH "/org/blueztools/obex" + +/* + * Type macros + */ +#define OBEX_AGENT_TYPE (obex_agent_get_type()) +#define OBEX_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEX_AGENT_TYPE, ObexAgent)) +#define OBEX_AGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEX_AGENT_TYPE)) +#define OBEX_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEX_AGENT_TYPE, ObexAgentClass)) +#define OBEX_AGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEX_AGENT_TYPE)) +#define OBEX_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEX_AGENT_TYPE, ObexAgentClass)) + +typedef struct _ObexAgent ObexAgent; +typedef struct _ObexAgentClass ObexAgentClass; +typedef struct _ObexAgentPrivate ObexAgentPrivate; + +struct _ObexAgent { + GObject parent_instance; + + /*< private >*/ + ObexAgentPrivate *priv; +}; + +struct _ObexAgentClass { + GObjectClass parent_class; +}; + +/* used by OBEX_AGENT_TYPE */ +GType obex_agent_get_type(void) G_GNUC_CONST; + +// agent released callback pointer function +typedef void (*ObexAgentReleasedCallback)(ObexAgent *obex_agent, gpointer user_data); + +// agent approved callback pointer function +typedef void (*ObexAgentApprovedCallback)(ObexAgent *obex_agent, const gchar* obex_transfer_path, const gchar *name, const guint64 size, gpointer user_data); + +/* + * Constructor + */ +ObexAgent *obex_agent_new(const gchar *root_folder); + +/* + * Method definitions + */ +void obex_agent_progress(ObexAgent *self, const gchar *transfer, guint64 transferred, GError **error); + +void obex_agent_set_release_callback(ObexAgent *self, ObexAgentReleasedCallback callback_function, gpointer user_data); +void obex_agent_clear_release_callback(ObexAgent *self); + +void obex_agent_set_approved_callback(ObexAgent *self, ObexAgentApprovedCallback callback_function, gpointer user_data); +void obex_agent_clear_approved_callback(ObexAgent *self); + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_AGENT_H */ + diff --git a/src/lib/obexd/obexagent.c b/src/lib/obexd/obexagent.c deleted file mode 100644 index a684154..0000000 --- a/src/lib/obexd/obexagent.c +++ /dev/null @@ -1,323 +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 <stdio.h> -#include <string.h> -#include <errno.h> - -#include <glib.h> -#include <dbus/dbus-glib.h> - -#include "../dbus-common.h" -#include "../helpers.h" - -#include "obexclient_transfer.h" -#include "obexagent.h" - -#define OBEXAGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXAGENT_TYPE, OBEXAgentPrivate)) - -struct _OBEXAgentPrivate { - /* Unused */ - DBusGProxy *proxy; - - /* Properties */ - gchar *root_folder; -}; - -G_DEFINE_TYPE(OBEXAgent, obexagent, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_ROOT_FOLDER, /* readwrite, construct only */ -}; - -static void _obexagent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _obexagent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -enum { - OBEXAGENT_RELEASED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void obexagent_dispose(GObject *gobject) -{ - OBEXAgent *self = OBEXAGENT(gobject); - - dbus_g_connection_unregister_g_object(session_conn, gobject); - - /* Proxy free */ - //g_object_unref(self->priv->proxy); - - /* Properties free */ - g_free(self->priv->root_folder); - - /* Chain up to the parent class */ - G_OBJECT_CLASS(obexagent_parent_class)->dispose(gobject); -} - -static void obexagent_class_init(OBEXAgentClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexagent_dispose; - - g_type_class_add_private(klass, sizeof(OBEXAgentPrivate)); - - /* Signals registation */ - signals[OBEXAGENT_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); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _obexagent_get_property; - gobject_class->set_property = _obexagent_set_property; - - /* string RootFolder [readwrite, construct only] */ - pspec = g_param_spec_string("RootFolder", "root_folder", "Root folder location", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property(gobject_class, PROP_ROOT_FOLDER, pspec); -} - -static void obexagent_init(OBEXAgent *self) -{ - self->priv = OBEXAGENT_GET_PRIVATE(self); - - g_assert(session_conn != NULL); - - /* Properties init */ - self->priv->root_folder = NULL; - - dbus_g_connection_register_g_object(session_conn, OBEXAGENT_DBUS_PATH, G_OBJECT(self)); - g_print("OBEXAgent registered\n"); -} - -static void _obexagent_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - OBEXAgent *self = OBEXAGENT(object); - - switch (property_id) { - case PROP_ROOT_FOLDER: - g_value_set_string(value, self->priv->root_folder); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _obexagent_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - OBEXAgent *self = OBEXAGENT(object); - - switch (property_id) { - case PROP_ROOT_FOLDER: - self->priv->root_folder = g_value_dup_string(value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -/* Methods */ - -/* Server API */ -gboolean obexagent_authorize(OBEXAgent *self, const gchar *transfer, const gchar *bt_address, const gchar *name, const gchar *type, gint length, gint time, gchar **ret, GError **error) -{ - g_assert(self->priv->root_folder != NULL && strlen(self->priv->root_folder) > 0); - - *ret = NULL; - g_print("[ObjectPush Request]\n"); - g_print(" Address: %s\n", bt_address); - g_print(" Name: %s\n", name); - if (type && strlen(type)) { - g_print(" Type: %s\n", type); - } - g_print(" Length: %d bytes\n", length); - /*if (time) { - g_print(" Time: %d\n", time); - }*/ - - gchar yn[4] = {0,}; - g_print("Accept (yes/no)? "); - 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) { - if (!g_path_is_absolute(self->priv->root_folder)) { - gchar *abs_path = get_absolute_path(self->priv->root_folder); - *ret = g_build_filename(abs_path, name, NULL); - g_free(abs_path); - } else { - *ret = g_build_filename(self->priv->root_folder, name, NULL); - } - - return TRUE; - } else { - // TODO: Fix error code - if (error) - *error = g_error_new(g_quark_from_static_string("org.openobex.Error.Rejected"), 0, "File transfer rejected"); - return FALSE; - } -} - -gboolean obexagent_cancel(OBEXAgent *self, GError **error) -{ - g_print("Request cancelled\n"); - return TRUE; -} - -/* Client API */ -static gboolean update_progress = FALSE; - -gboolean obexagent_release(OBEXAgent *self, GError **error) -{ - if (update_progress) { - g_print("\n"); - update_progress = FALSE; - } - - g_print("OBEXAgent released\n"); - - g_signal_emit(self, signals[OBEXAGENT_RELEASED], 0); - - return TRUE; -} - -gboolean obexagent_request(OBEXAgent *self, const gchar *transfer, gchar **ret, GError **error) -{ - *ret = NULL; - - if (intf_supported(OBEXC_DBUS_NAME, transfer, OBEXCLIENT_TRANSFER_DBUS_INTERFACE)) { - OBEXClientTransfer *transfer_t = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); - g_print("[Transfer Request]\n"); - g_print(" Name: %s\n", obexclient_transfer_get_name(transfer_t)); - g_print(" Size: %llu bytes\n", obexclient_transfer_get_size(transfer_t)); - g_print(" Filename: %s\n", obexclient_transfer_get_filename(transfer_t)); - g_object_unref(transfer_t); - - gchar yn[4] = {0,}; - g_print("Accept (yes/no)? "); - 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.openobex.Error.Rejected"), 0, "File transfer rejected"); - return FALSE; - } - } else { - g_print("Error: Unknown transfer request\n"); - // TODO: Fix error code - if (error) - *error = g_error_new(g_quark_from_static_string("org.openobex.Error.Rejected"), 0, "File transfer rejected"); - return FALSE; - } - - return TRUE; -} - -gboolean obexagent_progress(OBEXAgent *self, const gchar *transfer, guint64 transferred, GError **error) -{ - if (intf_supported(OBEXC_DBUS_NAME, transfer, OBEXCLIENT_TRANSFER_DBUS_INTERFACE)) { - OBEXClientTransfer *transfer_t = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); - guint64 total = obexclient_transfer_get_size(transfer_t); - - guint pp = (transferred / (gfloat) total)*100; - - if (!update_progress) { - g_print("[Transfer#%s] Progress: %3u%%", obexclient_transfer_get_name(transfer_t), pp); - update_progress = TRUE; - } else { - g_print("\b\b\b\b%3u%%", pp); - } - - if (pp == 100) { - g_print("\n"); - update_progress = FALSE; - } - - g_object_unref(transfer_t); - } - - return TRUE; -} - -gboolean obexagent_complete(OBEXAgent *self, const gchar *transfer, GError **error) -{ - if (update_progress) { - g_print("\n"); - update_progress = FALSE; - } - - if (intf_supported(OBEXC_DBUS_NAME, transfer, OBEXCLIENT_TRANSFER_DBUS_INTERFACE)) { - OBEXClientTransfer *transfer_t = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); - g_print("[Transfer#%s] Completed\n", obexclient_transfer_get_name(transfer_t)); - g_object_unref(transfer_t); - } - - return TRUE; -} - -gboolean obexagent_error(OBEXAgent *self, const gchar *transfer, const gchar *message, GError **error) -{ - if (update_progress) { - g_print("\n"); - update_progress = FALSE; - } - - g_print("[Transfer] Error: %s\n", message); - - /* - * Transfer interface does not exists - * Code commented - * - if (intf_supported(OBEXC_DBUS_NAME, transfer, OBEXCLIENT_TRANSFER_DBUS_INTERFACE)) { - OBEXClientTransfer *transfer_t = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); - g_print("[Transfer#%s] Error: %s\n", obexclient_transfer_get_name(transfer_t), message); - g_object_unref(transfer_t); - } - */ - - return TRUE; -} - diff --git a/src/lib/obexd/obexagent.h b/src/lib/obexd/obexagent.h deleted file mode 100644 index b94fb2c..0000000 --- a/src/lib/obexd/obexagent.h +++ /dev/null @@ -1,98 +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 __OBEXAGENT_H -#define __OBEXAGENT_H - -#include <glib-object.h> -#include <dbus/dbus-glib.h> - -#include "../marshallers.h" - -#define OBEXAGENT_DBUS_PATH "/ObexAgent" - -/* - * Type macros - */ -#define OBEXAGENT_TYPE (obexagent_get_type()) -#define OBEXAGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXAGENT_TYPE, OBEXAgent)) -#define OBEXAGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXAGENT_TYPE)) -#define OBEXAGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXAGENT_TYPE, OBEXAgentClass)) -#define OBEXAGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXAGENT_TYPE)) -#define OBEXAGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXAGENT_TYPE, OBEXAgentClass)) - -typedef struct _OBEXAgent OBEXAgent; -typedef struct _OBEXAgentClass OBEXAgentClass; -typedef struct _OBEXAgentPrivate OBEXAgentPrivate; - -struct _OBEXAgent { - GObject parent_instance; - - /*< private >*/ - OBEXAgentPrivate *priv; -}; - -struct _OBEXAgentClass { - GObjectClass parent_class; -}; - -/* used by OBEXAGENT_TYPE */ -GType obexagent_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ - -/* Server API */ -gboolean obexagent_authorize(OBEXAgent *self, const gchar *transfer, const gchar *bt_address, const gchar *name, const gchar *type, gint length, gint time, gchar **ret, GError **error); -gboolean obexagent_cancel(OBEXAgent *self, GError **error); - -/* Client API */ -gboolean obexagent_release(OBEXAgent *self, GError **error); -gboolean obexagent_request(OBEXAgent *self, const gchar *transfer, gchar **ret, GError **error); -gboolean obexagent_progress(OBEXAgent *self, const gchar *transfer, guint64 transferred, GError **error); -gboolean obexagent_complete(OBEXAgent *self, const gchar *transfer, GError **error); -gboolean obexagent_error(OBEXAgent *self, const gchar *transfer, const gchar *message, GError **error); - -/* Glue code */ -static const DBusGMethodInfo dbus_glib_obexagent_methods[] = { - { (GCallback) obexagent_authorize, g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER, 0}, - { (GCallback) obexagent_cancel, g_cclosure_bt_marshal_BOOLEAN__POINTER, 111}, - { (GCallback) obexagent_release, g_cclosure_bt_marshal_BOOLEAN__POINTER, 140}, - { (GCallback) obexagent_request, g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER_POINTER, 170}, - { (GCallback) obexagent_progress, g_cclosure_bt_marshal_BOOLEAN__BOXED_UINT64_POINTER, 226}, - { (GCallback) obexagent_complete, g_cclosure_bt_marshal_BOOLEAN__BOXED_POINTER, 286}, - { (GCallback) obexagent_error, g_cclosure_bt_marshal_BOOLEAN__BOXED_STRING_POINTER, 330}, -}; - -static const DBusGObjectInfo dbus_glib_obexagent_object_info = { - 0, - dbus_glib_obexagent_methods, - 7, - "org.openobex.Agent\0Authorize\0S\0transfer\0I\0o\0bt_address\0I\0s\0name\0I\0s\0type\0I\0s\0length\0I\0i\0time\0I\0i\0arg6\0O\0F\0N\0s\0\0org.openobex.Agent\0Cancel\0S\0\0org.openobex.Agent\0Release\0S\0\0org.openobex.Agent\0Request\0S\0transfer\0I\0o\0arg1\0O\0F\0N\0s\0\0org.openobex.Agent\0Progress\0S\0transfer\0I\0o\0transferred\0I\0t\0\0org.openobex.Agent\0Complete\0S\0transfer\0I\0o\0\0org.openobex.Agent\0Error\0S\0transfer\0I\0o\0message\0I\0s\0\0\0", - "\0", - "\0" -}; - -#endif /* __OBEXAGENT_H */ - diff --git a/src/lib/obexd/obexclient.c b/src/lib/obexd/obexclient.c deleted file mode 100644 index d8cfa78..0000000 --- a/src/lib/obexd/obexclient.c +++ /dev/null @@ -1,158 +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 "obexclient.h" - -#define OBEXCLIENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_TYPE, OBEXClientPrivate)) - -struct _OBEXClientPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; -}; - -G_DEFINE_TYPE(OBEXClient, obexclient, G_TYPE_OBJECT); - -static void obexclient_dispose(GObject *gobject) -{ - OBEXClient *self = OBEXCLIENT(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(obexclient_parent_class)->dispose(gobject); -} - -static void obexclient_class_init(OBEXClientClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexclient_dispose; - - g_type_class_add_private(klass, sizeof(OBEXClientPrivate)); -} - -static void obexclient_init(OBEXClient *self) -{ - self->priv = OBEXCLIENT_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(session_conn, "org.openobex.client", OBEXCLIENT_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=\"", OBEXCLIENT_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\"", OBEXCLIENT_DBUS_INTERFACE, OBEXCLIENT_DBUS_PATH); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(session_conn, "org.openobex.client", OBEXCLIENT_DBUS_PATH, OBEXCLIENT_DBUS_INTERFACE); -} - -/* Methods */ - -/* object CreateSession(dict device) */ -gchar *obexclient_create_session(OBEXClient *self, const GHashTable *device, GError **error) -{ - g_assert(OBEXCLIENT_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateSession", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); - - return ret; -} - -/* void ExchangeBusinessCards(dict device, string clientfile, string file) */ -void obexclient_exchange_business_cards(OBEXClient *self, const GHashTable *device, const gchar *clientfile, const gchar *file, GError **error) -{ - g_assert(OBEXCLIENT_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "ExchangeBusinessCards", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_STRING, clientfile, G_TYPE_STRING, file, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* string GetCapabilities(dict device) */ -gchar *obexclient_get_capabilities(OBEXClient *self, const GHashTable *device, GError **error) -{ - g_assert(OBEXCLIENT_IS(self)); - - gchar *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetCapabilities", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID); - - return ret; -} - -/* void PullBusinessCard(dict device, string file) */ -void obexclient_pull_business_card(OBEXClient *self, const GHashTable *device, const gchar *file, GError **error) -{ - g_assert(OBEXCLIENT_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "PullBusinessCard", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_STRING, file, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void RemoveSession(object session) */ -void obexclient_remove_session(OBEXClient *self, const gchar *session, GError **error) -{ - g_assert(OBEXCLIENT_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoveSession", error, DBUS_TYPE_G_OBJECT_PATH, session, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void SendFiles(dict device, array{string} files, object agent) */ -void obexclient_send_files(OBEXClient *self, const GHashTable *device, const gchar **files, const gchar *agent, GError **error) -{ - g_assert(OBEXCLIENT_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "SendFiles", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_STRV, files, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); -} - diff --git a/src/lib/obexd/obexclient.h b/src/lib/obexd/obexclient.h deleted file mode 100644 index d999b76..0000000 --- a/src/lib/obexd/obexclient.h +++ /dev/null @@ -1,71 +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 __OBEXCLIENT_H -#define __OBEXCLIENT_H - -#include <glib-object.h> - -#define OBEXCLIENT_DBUS_PATH "/" -#define OBEXCLIENT_DBUS_INTERFACE "org.openobex.Client" - -/* - * Type macros - */ -#define OBEXCLIENT_TYPE (obexclient_get_type()) -#define OBEXCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_TYPE, OBEXClient)) -#define OBEXCLIENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_TYPE)) -#define OBEXCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_TYPE, OBEXClientClass)) -#define OBEXCLIENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_TYPE)) -#define OBEXCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_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 OBEXCLIENT_TYPE */ -GType obexclient_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -gchar *obexclient_create_session(OBEXClient *self, const GHashTable *device, GError **error); -void obexclient_exchange_business_cards(OBEXClient *self, const GHashTable *device, const gchar *clientfile, const gchar *file, GError **error); -gchar *obexclient_get_capabilities(OBEXClient *self, const GHashTable *device, GError **error); -void obexclient_pull_business_card(OBEXClient *self, const GHashTable *device, const gchar *file, GError **error); -void obexclient_remove_session(OBEXClient *self, const gchar *session, GError **error); -void obexclient_send_files(OBEXClient *self, const GHashTable *device, const gchar **files, const gchar *agent, GError **error); - -#endif /* __OBEXCLIENT_H */ - diff --git a/src/lib/obexd/obexclient_file_transfer.c b/src/lib/obexd/obexclient_file_transfer.c deleted file mode 100644 index 05fa36d..0000000 --- a/src/lib/obexd/obexclient_file_transfer.c +++ /dev/null @@ -1,240 +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 "obexclient_file_transfer.h" - -#define OBEXCLIENT_FILE_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransferPrivate)) - -struct _OBEXClientFileTransferPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; -}; - -G_DEFINE_TYPE(OBEXClientFileTransfer, obexclient_file_transfer, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ -}; - -static void _obexclient_file_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _obexclient_file_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -static void obexclient_file_transfer_dispose(GObject *gobject) -{ - OBEXClientFileTransfer *self = OBEXCLIENT_FILE_TRANSFER(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(obexclient_file_transfer_parent_class)->dispose(gobject); -} - -static void obexclient_file_transfer_class_init(OBEXClientFileTransferClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexclient_file_transfer_dispose; - - g_type_class_add_private(klass, sizeof(OBEXClientFileTransferPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _obexclient_file_transfer_get_property; - gobject_class->set_property = _obexclient_file_transfer_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 obexclient_file_transfer_init(OBEXClientFileTransfer *self) -{ - self->priv = OBEXCLIENT_FILE_TRANSFER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); -} - -static void obexclient_file_transfer_post_init(OBEXClientFileTransfer *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(session_conn, "org.openobex.client", 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=\"", OBEXCLIENT_FILE_TRANSFER_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\"", OBEXCLIENT_FILE_TRANSFER_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(session_conn, "org.openobex.client", dbus_object_path, OBEXCLIENT_FILE_TRANSFER_DBUS_INTERFACE); -} - -static void _obexclient_file_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - OBEXClientFileTransfer *self = OBEXCLIENT_FILE_TRANSFER(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, obexclient_file_transfer_get_dbus_object_path(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _obexclient_file_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - OBEXClientFileTransfer *self = OBEXCLIENT_FILE_TRANSFER(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - obexclient_file_transfer_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 ChangeFolder(string folder) */ -void obexclient_file_transfer_change_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "ChangeFolder", error, G_TYPE_STRING, folder, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void CopyFile(string sourcefile, string targetfile) */ -void obexclient_file_transfer_copy_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "CopyFile", error, G_TYPE_STRING, sourcefile, G_TYPE_STRING, targetfile, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void CreateFolder(string folder) */ -void obexclient_file_transfer_create_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateFolder", error, G_TYPE_STRING, folder, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void Delete(string file) */ -void obexclient_file_transfer_delete(OBEXClientFileTransfer *self, const gchar *file, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Delete", error, G_TYPE_STRING, file, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void GetFile(string targetfile, string sourcefile) */ -void obexclient_file_transfer_get_file(OBEXClientFileTransfer *self, const gchar *targetfile, const gchar *sourcefile, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetFile", error, G_TYPE_STRING, targetfile, G_TYPE_STRING, sourcefile, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* array{dict} ListFolder() */ -GPtrArray *obexclient_file_transfer_list_folder(OBEXClientFileTransfer *self, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - GPtrArray *ret = NULL; - dbus_g_proxy_call(self->priv->dbus_g_proxy, "ListFolder", error, G_TYPE_INVALID, DBUS_TYPE_G_HASH_TABLE_ARRAY, &ret, G_TYPE_INVALID); - - return ret; -} - -/* void MoveFile(string sourcefile, string targetfile) */ -void obexclient_file_transfer_move_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "MoveFile", error, G_TYPE_STRING, sourcefile, G_TYPE_STRING, targetfile, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void PutFile(string sourcefile, string targetfile) */ -void obexclient_file_transfer_put_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "PutFile", error, G_TYPE_STRING, sourcefile, G_TYPE_STRING, targetfile, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* Properties access methods */ -const gchar *obexclient_file_transfer_get_dbus_object_path(OBEXClientFileTransfer *self) -{ - g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - diff --git a/src/lib/obexd/obexclient_file_transfer.h b/src/lib/obexd/obexclient_file_transfer.h deleted file mode 100644 index 5e796b2..0000000 --- a/src/lib/obexd/obexclient_file_transfer.h +++ /dev/null @@ -1,74 +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 __OBEXCLIENT_FILE_TRANSFER_H -#define __OBEXCLIENT_FILE_TRANSFER_H - -#include <glib-object.h> - -#define OBEXCLIENT_FILE_TRANSFER_DBUS_INTERFACE "org.openobex.FileTransfer" - -/* - * Type macros - */ -#define OBEXCLIENT_FILE_TRANSFER_TYPE (obexclient_file_transfer_get_type()) -#define OBEXCLIENT_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransfer)) -#define OBEXCLIENT_FILE_TRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_FILE_TRANSFER_TYPE)) -#define OBEXCLIENT_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransferClass)) -#define OBEXCLIENT_FILE_TRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_FILE_TRANSFER_TYPE)) -#define OBEXCLIENT_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransferClass)) - -typedef struct _OBEXClientFileTransfer OBEXClientFileTransfer; -typedef struct _OBEXClientFileTransferClass OBEXClientFileTransferClass; -typedef struct _OBEXClientFileTransferPrivate OBEXClientFileTransferPrivate; - -struct _OBEXClientFileTransfer { - GObject parent_instance; - - /*< private >*/ - OBEXClientFileTransferPrivate *priv; -}; - -struct _OBEXClientFileTransferClass { - GObjectClass parent_class; -}; - -/* used by OBEXCLIENT_FILE_TRANSFER_TYPE */ -GType obexclient_file_transfer_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void obexclient_file_transfer_change_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error); -void obexclient_file_transfer_copy_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); -void obexclient_file_transfer_create_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error); -void obexclient_file_transfer_delete(OBEXClientFileTransfer *self, const gchar *file, GError **error); -void obexclient_file_transfer_get_file(OBEXClientFileTransfer *self, const gchar *targetfile, const gchar *sourcefile, GError **error); -GPtrArray *obexclient_file_transfer_list_folder(OBEXClientFileTransfer *self, GError **error); -void obexclient_file_transfer_move_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); -void obexclient_file_transfer_put_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); - -const gchar *obexclient_file_transfer_get_dbus_object_path(OBEXClientFileTransfer *self); - -#endif /* __OBEXCLIENT_FILE_TRANSFER_H */ - diff --git a/src/lib/obexd/obexclient_session.c b/src/lib/obexd/obexclient_session.c deleted file mode 100644 index a5b52f8..0000000 --- a/src/lib/obexd/obexclient_session.c +++ /dev/null @@ -1,288 +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 "obexclient_session.h" - -#define OBEXCLIENT_SESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_SESSION_TYPE, OBEXClientSessionPrivate)) - -struct _OBEXClientSessionPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - guchar channel; - gchar *destination; - gchar *source; -}; - -G_DEFINE_TYPE(OBEXClientSession, obexclient_session, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_CHANNEL, /* readonly */ - PROP_DESTINATION, /* readonly */ - PROP_SOURCE /* readonly */ -}; - -static void _obexclient_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _obexclient_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -static void obexclient_session_dispose(GObject *gobject) -{ - OBEXClientSession *self = OBEXCLIENT_SESSION(gobject); - - /* Properties free */ - g_free(self->priv->destination); - g_free(self->priv->source); - - /* 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(obexclient_session_parent_class)->dispose(gobject); -} - -static void obexclient_session_class_init(OBEXClientSessionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexclient_session_dispose; - - g_type_class_add_private(klass, sizeof(OBEXClientSessionPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _obexclient_session_get_property; - gobject_class->set_property = _obexclient_session_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); - - /* byte Channel [readonly] */ - pspec = g_param_spec_uchar("Channel", NULL, NULL, 0, 0xFF, 0, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_CHANNEL, pspec); - - /* string Destination [readonly] */ - pspec = g_param_spec_string("Destination", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_DESTINATION, pspec); - - /* string Source [readonly] */ - pspec = g_param_spec_string("Source", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_SOURCE, pspec); -} - -static void obexclient_session_init(OBEXClientSession *self) -{ - self->priv = OBEXCLIENT_SESSION_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); -} - -static void obexclient_session_post_init(OBEXClientSession *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(session_conn, "org.openobex.client", 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=\"", OBEXCLIENT_SESSION_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\"", OBEXCLIENT_SESSION_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(session_conn, "org.openobex.client", dbus_object_path, OBEXCLIENT_SESSION_DBUS_INTERFACE); - - /* Properties init */ - GHashTable *properties = obexclient_session_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* byte Channel [readonly] */ - if (g_hash_table_lookup(properties, "Channel")) { - self->priv->channel = g_value_get_uchar(g_hash_table_lookup(properties, "Channel")); - } else { - self->priv->channel = 0; - } - - /* string Destination [readonly] */ - if (g_hash_table_lookup(properties, "Destination")) { - self->priv->destination = g_value_dup_string(g_hash_table_lookup(properties, "Destination")); - } else { - self->priv->destination = g_strdup("undefined"); - } - - /* string Source [readonly] */ - if (g_hash_table_lookup(properties, "Source")) { - self->priv->source = g_value_dup_string(g_hash_table_lookup(properties, "Source")); - } else { - self->priv->source = g_strdup("undefined"); - } - - g_hash_table_unref(properties); -} - -static void _obexclient_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - OBEXClientSession *self = OBEXCLIENT_SESSION(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, obexclient_session_get_dbus_object_path(self)); - break; - - case PROP_CHANNEL: - g_value_set_uchar(value, obexclient_session_get_channel(self)); - break; - - case PROP_DESTINATION: - g_value_set_string(value, obexclient_session_get_destination(self)); - break; - - case PROP_SOURCE: - g_value_set_string(value, obexclient_session_get_source(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _obexclient_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - OBEXClientSession *self = OBEXCLIENT_SESSION(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - obexclient_session_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 AssignAgent(object agent) */ -void obexclient_session_assign_agent(OBEXClientSession *self, const gchar *agent, GError **error) -{ - g_assert(OBEXCLIENT_SESSION_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "AssignAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* dict GetProperties() */ -GHashTable *obexclient_session_get_properties(OBEXClientSession *self, GError **error) -{ - g_assert(OBEXCLIENT_SESSION_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; -} - -/* void ReleaseAgent(object agent) */ -void obexclient_session_release_agent(OBEXClientSession *self, const gchar *agent, GError **error) -{ - g_assert(OBEXCLIENT_SESSION_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "ReleaseAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* Properties access methods */ -const gchar *obexclient_session_get_dbus_object_path(OBEXClientSession *self) -{ - g_assert(OBEXCLIENT_SESSION_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - -const guchar obexclient_session_get_channel(OBEXClientSession *self) -{ - g_assert(OBEXCLIENT_SESSION_IS(self)); - - return self->priv->channel; -} - -const gchar *obexclient_session_get_destination(OBEXClientSession *self) -{ - g_assert(OBEXCLIENT_SESSION_IS(self)); - - return self->priv->destination; -} - -const gchar *obexclient_session_get_source(OBEXClientSession *self) -{ - g_assert(OBEXCLIENT_SESSION_IS(self)); - - return self->priv->source; -} - diff --git a/src/lib/obexd/obexclient_session.h b/src/lib/obexd/obexclient_session.h deleted file mode 100644 index 87af06d..0000000 --- a/src/lib/obexd/obexclient_session.h +++ /dev/null @@ -1,72 +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 __OBEXCLIENT_SESSION_H -#define __OBEXCLIENT_SESSION_H - -#include <glib-object.h> - -#define OBEXCLIENT_SESSION_DBUS_INTERFACE "org.openobex.Session" - -/* - * Type macros - */ -#define OBEXCLIENT_SESSION_TYPE (obexclient_session_get_type()) -#define OBEXCLIENT_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_SESSION_TYPE, OBEXClientSession)) -#define OBEXCLIENT_SESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_SESSION_TYPE)) -#define OBEXCLIENT_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_SESSION_TYPE, OBEXClientSessionClass)) -#define OBEXCLIENT_SESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_SESSION_TYPE)) -#define OBEXCLIENT_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_SESSION_TYPE, OBEXClientSessionClass)) - -typedef struct _OBEXClientSession OBEXClientSession; -typedef struct _OBEXClientSessionClass OBEXClientSessionClass; -typedef struct _OBEXClientSessionPrivate OBEXClientSessionPrivate; - -struct _OBEXClientSession { - GObject parent_instance; - - /*< private >*/ - OBEXClientSessionPrivate *priv; -}; - -struct _OBEXClientSessionClass { - GObjectClass parent_class; -}; - -/* used by OBEXCLIENT_SESSION_TYPE */ -GType obexclient_session_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void obexclient_session_assign_agent(OBEXClientSession *self, const gchar *agent, GError **error); -GHashTable *obexclient_session_get_properties(OBEXClientSession *self, GError **error); -void obexclient_session_release_agent(OBEXClientSession *self, const gchar *agent, GError **error); - -const gchar *obexclient_session_get_dbus_object_path(OBEXClientSession *self); -const guchar obexclient_session_get_channel(OBEXClientSession *self); -const gchar *obexclient_session_get_destination(OBEXClientSession *self); -const gchar *obexclient_session_get_source(OBEXClientSession *self); - -#endif /* __OBEXCLIENT_SESSION_H */ - diff --git a/src/lib/obexd/obexclient_transfer.c b/src/lib/obexd/obexclient_transfer.c deleted file mode 100644 index 68c4bf3..0000000 --- a/src/lib/obexd/obexclient_transfer.c +++ /dev/null @@ -1,280 +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 "obexclient_transfer.h" - -#define OBEXCLIENT_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransferPrivate)) - -struct _OBEXClientTransferPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gchar *filename; - gchar *name; - guint64 size; -}; - -G_DEFINE_TYPE(OBEXClientTransfer, obexclient_transfer, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_FILENAME, /* readonly */ - PROP_NAME, /* readonly */ - PROP_SIZE /* readonly */ -}; - -static void _obexclient_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _obexclient_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -static void obexclient_transfer_dispose(GObject *gobject) -{ - OBEXClientTransfer *self = OBEXCLIENT_TRANSFER(gobject); - - /* Properties free */ - g_free(self->priv->filename); - g_free(self->priv->name); - - /* 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(obexclient_transfer_parent_class)->dispose(gobject); -} - -static void obexclient_transfer_class_init(OBEXClientTransferClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexclient_transfer_dispose; - - g_type_class_add_private(klass, sizeof(OBEXClientTransferPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _obexclient_transfer_get_property; - gobject_class->set_property = _obexclient_transfer_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 Filename [readonly] */ - pspec = g_param_spec_string("Filename", NULL, NULL, NULL, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_FILENAME, 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); - - /* uint64 Size [readonly] */ - pspec = g_param_spec_uint64("Size", NULL, NULL, 0, 0xFFFFFFFFFFFFFFFF, 0, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_SIZE, pspec); -} - -static void obexclient_transfer_init(OBEXClientTransfer *self) -{ - self->priv = OBEXCLIENT_TRANSFER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); -} - -static void obexclient_transfer_post_init(OBEXClientTransfer *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(session_conn, "org.openobex.client", 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=\"", OBEXCLIENT_TRANSFER_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\"", OBEXCLIENT_TRANSFER_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(session_conn, "org.openobex.client", dbus_object_path, OBEXCLIENT_TRANSFER_DBUS_INTERFACE); - - /* Properties init */ - GHashTable *properties = obexclient_transfer_get_properties(self, &error); - if (error != NULL) { - g_critical("%s", error->message); - } - g_assert(error == NULL); - g_assert(properties != NULL); - - /* string Filename [readonly] */ - if (g_hash_table_lookup(properties, "Filename")) { - self->priv->filename = g_value_dup_string(g_hash_table_lookup(properties, "Filename")); - } else { - self->priv->filename = g_strdup("undefined"); - } - - /* 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"); - } - - /* uint64 Size [readonly] */ - if (g_hash_table_lookup(properties, "Size")) { - self->priv->size = g_value_get_uint64(g_hash_table_lookup(properties, "Size")); - } else { - self->priv->size = 0; - } - - g_hash_table_unref(properties); -} - -static void _obexclient_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - OBEXClientTransfer *self = OBEXCLIENT_TRANSFER(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, obexclient_transfer_get_dbus_object_path(self)); - break; - - case PROP_FILENAME: - g_value_set_string(value, obexclient_transfer_get_filename(self)); - break; - - case PROP_NAME: - g_value_set_string(value, obexclient_transfer_get_name(self)); - break; - - case PROP_SIZE: - g_value_set_uint64(value, obexclient_transfer_get_size(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _obexclient_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - OBEXClientTransfer *self = OBEXCLIENT_TRANSFER(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - obexclient_transfer_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 Cancel() */ -void obexclient_transfer_cancel(OBEXClientTransfer *self, GError **error) -{ - g_assert(OBEXCLIENT_TRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Cancel", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* dict GetProperties() */ -GHashTable *obexclient_transfer_get_properties(OBEXClientTransfer *self, GError **error) -{ - g_assert(OBEXCLIENT_TRANSFER_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 *obexclient_transfer_get_dbus_object_path(OBEXClientTransfer *self) -{ - g_assert(OBEXCLIENT_TRANSFER_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - -const gchar *obexclient_transfer_get_filename(OBEXClientTransfer *self) -{ - g_assert(OBEXCLIENT_TRANSFER_IS(self)); - - return self->priv->filename; -} - -const gchar *obexclient_transfer_get_name(OBEXClientTransfer *self) -{ - g_assert(OBEXCLIENT_TRANSFER_IS(self)); - - return self->priv->name; -} - -const guint64 obexclient_transfer_get_size(OBEXClientTransfer *self) -{ - g_assert(OBEXCLIENT_TRANSFER_IS(self)); - - return self->priv->size; -} - diff --git a/src/lib/obexd/obexclient_transfer.h b/src/lib/obexd/obexclient_transfer.h deleted file mode 100644 index f84fd69..0000000 --- a/src/lib/obexd/obexclient_transfer.h +++ /dev/null @@ -1,71 +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 __OBEXCLIENT_TRANSFER_H -#define __OBEXCLIENT_TRANSFER_H - -#include <glib-object.h> - -#define OBEXCLIENT_TRANSFER_DBUS_INTERFACE "org.openobex.Transfer" - -/* - * Type macros - */ -#define OBEXCLIENT_TRANSFER_TYPE (obexclient_transfer_get_type()) -#define OBEXCLIENT_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransfer)) -#define OBEXCLIENT_TRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_TRANSFER_TYPE)) -#define OBEXCLIENT_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransferClass)) -#define OBEXCLIENT_TRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_TRANSFER_TYPE)) -#define OBEXCLIENT_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransferClass)) - -typedef struct _OBEXClientTransfer OBEXClientTransfer; -typedef struct _OBEXClientTransferClass OBEXClientTransferClass; -typedef struct _OBEXClientTransferPrivate OBEXClientTransferPrivate; - -struct _OBEXClientTransfer { - GObject parent_instance; - - /*< private >*/ - OBEXClientTransferPrivate *priv; -}; - -struct _OBEXClientTransferClass { - GObjectClass parent_class; -}; - -/* used by OBEXCLIENT_TRANSFER_TYPE */ -GType obexclient_transfer_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void obexclient_transfer_cancel(OBEXClientTransfer *self, GError **error); -GHashTable *obexclient_transfer_get_properties(OBEXClientTransfer *self, GError **error); - -const gchar *obexclient_transfer_get_dbus_object_path(OBEXClientTransfer *self); -const gchar *obexclient_transfer_get_filename(OBEXClientTransfer *self); -const gchar *obexclient_transfer_get_name(OBEXClientTransfer *self); -const guint64 obexclient_transfer_get_size(OBEXClientTransfer *self); - -#endif /* __OBEXCLIENT_TRANSFER_H */ - diff --git a/src/lib/obexd/obexmanager.c b/src/lib/obexd/obexmanager.c deleted file mode 100644 index 1e3e0d4..0000000 --- a/src/lib/obexd/obexmanager.c +++ /dev/null @@ -1,218 +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 "obexmanager.h" - -#define OBEXMANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXMANAGER_TYPE, OBEXManagerPrivate)) - -struct _OBEXManagerPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; -}; - -G_DEFINE_TYPE(OBEXManager, obexmanager, G_TYPE_OBJECT); - -enum { - SESSION_CREATED, - SESSION_REMOVED, - TRANSFER_COMPLETED, - TRANSFER_STARTED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void session_created_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data); -static void session_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data); -static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, const gboolean success, gpointer data); -static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, gpointer data); - -static void obexmanager_dispose(GObject *gobject) -{ - OBEXManager *self = OBEXMANAGER(gobject); - - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionCreated", G_CALLBACK(session_created_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionRemoved", G_CALLBACK(session_removed_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self); - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self); - - /* 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(obexmanager_parent_class)->dispose(gobject); -} - -static void obexmanager_class_init(OBEXManagerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexmanager_dispose; - - g_type_class_add_private(klass, sizeof(OBEXManagerPrivate)); - - /* Signals registation */ - signals[SESSION_CREATED] = g_signal_new("SessionCreated", - 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[SESSION_REMOVED] = g_signal_new("SessionRemoved", - 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[TRANSFER_COMPLETED] = g_signal_new("TransferCompleted", - 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_BOOLEAN, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN); - - signals[TRANSFER_STARTED] = g_signal_new("TransferStarted", - 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); -} - -static void obexmanager_init(OBEXManager *self) -{ - self->priv = OBEXMANAGER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); - - GError *error = NULL; - - /* Getting introspection XML */ - self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(session_conn, "org.openobex", OBEXMANAGER_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=\"", OBEXMANAGER_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\"", OBEXMANAGER_DBUS_INTERFACE, OBEXMANAGER_DBUS_PATH); - g_assert(FALSE); - } - g_free(check_intf_regex_str); - - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(session_conn, "org.openobex", OBEXMANAGER_DBUS_PATH, OBEXMANAGER_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* SessionCreated(object session) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionCreated", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionCreated", G_CALLBACK(session_created_handler), self, NULL); - - /* SessionRemoved(object session) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionRemoved", G_CALLBACK(session_removed_handler), self, NULL); - - /* TransferCompleted(object transfer, boolean success) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferCompleted", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self, NULL); - - /* TransferStarted(object transfer) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferStarted", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self, NULL); -} - -/* Methods */ - -/* void RegisterAgent(object agent) */ -void obexmanager_register_agent(OBEXManager *self, const gchar *agent, GError **error) -{ - g_assert(OBEXMANAGER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "RegisterAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* void UnregisterAgent(object agent) */ -void obexmanager_unregister_agent(OBEXManager *self, const gchar *agent, GError **error) -{ - g_assert(OBEXMANAGER_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); -} - -/* Signals handlers */ -static void session_created_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data) -{ - OBEXManager *self = OBEXMANAGER(data); - - g_signal_emit(self, signals[SESSION_CREATED], 0, session); -} - -static void session_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data) -{ - OBEXManager *self = OBEXMANAGER(data); - - g_signal_emit(self, signals[SESSION_REMOVED], 0, session); -} - -static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, const gboolean success, gpointer data) -{ - OBEXManager *self = OBEXMANAGER(data); - - g_signal_emit(self, signals[TRANSFER_COMPLETED], 0, transfer, success); -} - -static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, gpointer data) -{ - OBEXManager *self = OBEXMANAGER(data); - - g_signal_emit(self, signals[TRANSFER_STARTED], 0, transfer); -} - diff --git a/src/lib/obexd/obexmanager.h b/src/lib/obexd/obexmanager.h deleted file mode 100644 index 203fe59..0000000 --- a/src/lib/obexd/obexmanager.h +++ /dev/null @@ -1,67 +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 __OBEXMANAGER_H -#define __OBEXMANAGER_H - -#include <glib-object.h> - -#define OBEXMANAGER_DBUS_PATH "/" -#define OBEXMANAGER_DBUS_INTERFACE "org.openobex.Manager" - -/* - * Type macros - */ -#define OBEXMANAGER_TYPE (obexmanager_get_type()) -#define OBEXMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXMANAGER_TYPE, OBEXManager)) -#define OBEXMANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXMANAGER_TYPE)) -#define OBEXMANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXMANAGER_TYPE, OBEXManagerClass)) -#define OBEXMANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXMANAGER_TYPE)) -#define OBEXMANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXMANAGER_TYPE, OBEXManagerClass)) - -typedef struct _OBEXManager OBEXManager; -typedef struct _OBEXManagerClass OBEXManagerClass; -typedef struct _OBEXManagerPrivate OBEXManagerPrivate; - -struct _OBEXManager { - GObject parent_instance; - - /*< private >*/ - OBEXManagerPrivate *priv; -}; - -struct _OBEXManagerClass { - GObjectClass parent_class; -}; - -/* used by OBEXMANAGER_TYPE */ -GType obexmanager_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void obexmanager_register_agent(OBEXManager *self, const gchar *agent, GError **error); -void obexmanager_unregister_agent(OBEXManager *self, const gchar *agent, GError **error); - -#endif /* __OBEXMANAGER_H */ - diff --git a/src/lib/obexd/obexsession.c b/src/lib/obexd/obexsession.c deleted file mode 100644 index 48380cf..0000000 --- a/src/lib/obexd/obexsession.c +++ /dev/null @@ -1,223 +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 "obexsession.h" - -#define OBEXSESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXSESSION_TYPE, OBEXSessionPrivate)) - -struct _OBEXSessionPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; - - /* Properties */ - gchar *address; -}; - -G_DEFINE_TYPE(OBEXSession, obexsession, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ - PROP_ADDRESS /* readonly */ -}; - -static void _obexsession_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _obexsession_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -static void obexsession_dispose(GObject *gobject) -{ - OBEXSession *self = OBEXSESSION(gobject); - - /* Properties free */ - g_free(self->priv->address); - - /* 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(obexsession_parent_class)->dispose(gobject); -} - -static void obexsession_class_init(OBEXSessionClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obexsession_dispose; - - g_type_class_add_private(klass, sizeof(OBEXSessionPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _obexsession_get_property; - gobject_class->set_property = _obexsession_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); -} - -static void obexsession_init(OBEXSession *self) -{ - self->priv = OBEXSESSION_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); -} - -static void obexsession_post_init(OBEXSession *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(session_conn, "org.openobex", 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=\"", OBEXSESSION_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\"", OBEXSESSION_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(session_conn, "org.openobex", dbus_object_path, OBEXSESSION_DBUS_INTERFACE); - - /* Properties init */ - GHashTable *properties = obexsession_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"); - } - - g_hash_table_unref(properties); -} - -static void _obexsession_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - OBEXSession *self = OBEXSESSION(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, obexsession_get_dbus_object_path(self)); - break; - - case PROP_ADDRESS: - g_value_set_string(value, obexsession_get_address(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _obexsession_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - OBEXSession *self = OBEXSESSION(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - obexsession_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 */ - -/* dict GetProperties() */ -GHashTable *obexsession_get_properties(OBEXSession *self, GError **error) -{ - g_assert(OBEXSESSION_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 *obexsession_get_dbus_object_path(OBEXSession *self) -{ - g_assert(OBEXSESSION_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - -const gchar *obexsession_get_address(OBEXSession *self) -{ - g_assert(OBEXSESSION_IS(self)); - - return self->priv->address; -} - diff --git a/src/lib/obexd/obexsession.h b/src/lib/obexd/obexsession.h deleted file mode 100644 index d39e15f..0000000 --- a/src/lib/obexd/obexsession.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 __OBEXSESSION_H -#define __OBEXSESSION_H - -#include <glib-object.h> - -#define OBEXSESSION_DBUS_INTERFACE "org.openobex.Session" - -/* - * Type macros - */ -#define OBEXSESSION_TYPE (obexsession_get_type()) -#define OBEXSESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXSESSION_TYPE, OBEXSession)) -#define OBEXSESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXSESSION_TYPE)) -#define OBEXSESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXSESSION_TYPE, OBEXSessionClass)) -#define OBEXSESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXSESSION_TYPE)) -#define OBEXSESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXSESSION_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 OBEXSESSION_TYPE */ -GType obexsession_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -GHashTable *obexsession_get_properties(OBEXSession *self, GError **error); - -const gchar *obexsession_get_dbus_object_path(OBEXSession *self); -const gchar *obexsession_get_address(OBEXSession *self); - -#endif /* __OBEXSESSION_H */ - diff --git a/src/lib/obexd/obextransfer.c b/src/lib/obexd/obextransfer.c deleted file mode 100644 index 78dcf52..0000000 --- a/src/lib/obexd/obextransfer.c +++ /dev/null @@ -1,216 +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 "obextransfer.h" - -#define OBEXTRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXTRANSFER_TYPE, OBEXTransferPrivate)) - -struct _OBEXTransferPrivate { - DBusGProxy *dbus_g_proxy; - - /* Introspection data */ - DBusGProxy *introspection_g_proxy; - gchar *introspection_xml; -}; - -G_DEFINE_TYPE(OBEXTransfer, obextransfer, G_TYPE_OBJECT); - -enum { - PROP_0, - - PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ -}; - -static void _obextransfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void _obextransfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); - -enum { - PROGRESS, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -static void progress_handler(DBusGProxy *dbus_g_proxy, const gint32 total, const gint32 transfered, gpointer data); - -static void obextransfer_dispose(GObject *gobject) -{ - OBEXTransfer *self = OBEXTRANSFER(gobject); - - /* DBus signals disconnection */ - dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Progress", G_CALLBACK(progress_handler), self); - - /* 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(obextransfer_parent_class)->dispose(gobject); -} - -static void obextransfer_class_init(OBEXTransferClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->dispose = obextransfer_dispose; - - g_type_class_add_private(klass, sizeof(OBEXTransferPrivate)); - - /* Properties registration */ - GParamSpec *pspec; - - gobject_class->get_property = _obextransfer_get_property; - gobject_class->set_property = _obextransfer_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); - - /* Signals registation */ - signals[PROGRESS] = g_signal_new("Progress", - 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__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); -} - -static void obextransfer_init(OBEXTransfer *self) -{ - self->priv = OBEXTRANSFER_GET_PRIVATE(self); - - /* DBusGProxy init */ - self->priv->dbus_g_proxy = NULL; - - g_assert(session_conn != NULL); -} - -static void obextransfer_post_init(OBEXTransfer *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(session_conn, "org.openobex", 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=\"", OBEXTRANSFER_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\"", OBEXTRANSFER_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(session_conn, "org.openobex", dbus_object_path, OBEXTRANSFER_DBUS_INTERFACE); - - /* DBus signals connection */ - - /* Progress(int32 total, int32 transfered) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Progress", G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Progress", G_CALLBACK(progress_handler), self, NULL); -} - -static void _obextransfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - OBEXTransfer *self = OBEXTRANSFER(object); - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - g_value_set_string(value, obextransfer_get_dbus_object_path(self)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } -} - -static void _obextransfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - OBEXTransfer *self = OBEXTRANSFER(object); - GError *error = NULL; - - switch (property_id) { - case PROP_DBUS_OBJECT_PATH: - obextransfer_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 Cancel() */ -void obextransfer_cancel(OBEXTransfer *self, GError **error) -{ - g_assert(OBEXTRANSFER_IS(self)); - - dbus_g_proxy_call(self->priv->dbus_g_proxy, "Cancel", error, G_TYPE_INVALID, G_TYPE_INVALID); -} - -/* Properties access methods */ -const gchar *obextransfer_get_dbus_object_path(OBEXTransfer *self) -{ - g_assert(OBEXTRANSFER_IS(self)); - - return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); -} - -/* Signals handlers */ -static void progress_handler(DBusGProxy *dbus_g_proxy, const gint32 total, const gint32 transfered, gpointer data) -{ - OBEXTransfer *self = OBEXTRANSFER(data); - - g_signal_emit(self, signals[PROGRESS], 0, total, transfered); -} - diff --git a/src/lib/obexd/obextransfer.h b/src/lib/obexd/obextransfer.h deleted file mode 100644 index 99f3084..0000000 --- a/src/lib/obexd/obextransfer.h +++ /dev/null @@ -1,67 +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 __OBEXTRANSFER_H -#define __OBEXTRANSFER_H - -#include <glib-object.h> - -#define OBEXTRANSFER_DBUS_INTERFACE "org.openobex.Transfer" - -/* - * Type macros - */ -#define OBEXTRANSFER_TYPE (obextransfer_get_type()) -#define OBEXTRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXTRANSFER_TYPE, OBEXTransfer)) -#define OBEXTRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXTRANSFER_TYPE)) -#define OBEXTRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXTRANSFER_TYPE, OBEXTransferClass)) -#define OBEXTRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXTRANSFER_TYPE)) -#define OBEXTRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXTRANSFER_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 OBEXTRANSFER_TYPE */ -GType obextransfer_get_type(void) G_GNUC_CONST; - -/* - * Method definitions - */ -void obextransfer_cancel(OBEXTransfer *self, GError **error); - -const gchar *obextransfer_get_dbus_object_path(OBEXTransfer *self); - -#endif /* __OBEXTRANSFER_H */ - diff --git a/src/lib/properties.c b/src/lib/properties.c new file mode 100644 index 0000000..8b913d5 --- /dev/null +++ b/src/lib/properties.c @@ -0,0 +1,269 @@ +#include <gio/gio.h> +#include "dbus-common.h" +#include "properties.h" + +struct _PropertiesPrivate +{ + GDBusProxy *proxy; + + // a{sa{sv}} + GVariant *dict_interfaces; + + gchar *dbus_type; + gchar *dbus_service_name; + gchar *dbus_object_path; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (Properties, properties, G_TYPE_OBJECT) + +enum +{ + PROP_0, + + PROP_DBUS_TYPE, + PROP_DBUS_SERVICE_NAME, + PROP_DBUS_OBJECT_PATH, + + N_PROPERTIES +}; + +/* Keep a pointer to the properties definition */ +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + +/* + * Private method definitions + */ +static void _properties_create_gdbus_proxy(Properties *self, GError **error); + +/* + * Methods + */ +static void _properties_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Properties *self = PROPERTIES(object); + GError *error = NULL; + + switch (property_id) + { +// case PROP_EXAMPLE: +// g_free(self->priv->example); +// self->priv->example = g_value_dup_string(value); +// g_print("example: %s\n", self->priv->example); +// break; + + case PROP_DBUS_TYPE: + if(self->priv->dbus_type) + g_free(self->priv->dbus_type); + self->priv->dbus_type = g_value_dup_string(value); + // _properties_set_dbus_object_path(self, g_value_dup_string(value), &error); + _properties_create_gdbus_proxy(self, &error); + break; + + case PROP_DBUS_SERVICE_NAME: + if(self->priv->dbus_service_name) + g_free(self->priv->dbus_service_name); + self->priv->dbus_service_name = g_value_dup_string(value); + // _properties_set_dbus_object_path(self, g_value_dup_string(value), &error); + _properties_create_gdbus_proxy(self, &error); + break; + + case PROP_DBUS_OBJECT_PATH: + if(self->priv->dbus_object_path) + g_free(self->priv->dbus_object_path); + self->priv->dbus_object_path = g_value_dup_string(value); + // _properties_set_dbus_object_path(self, g_value_dup_string(value), &error); + _properties_create_gdbus_proxy(self, &error); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + g_assert(error == NULL); +} + +static void _properties_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Properties *self = PROPERTIES(object); + + switch (property_id) + { +// case PROP_EXAMPLE: +// g_value_set_string(value, self->priv->example); +// break; + + case PROP_DBUS_TYPE: + g_value_set_string(value, properties_get_dbus_type(self)); + break; + + case PROP_DBUS_SERVICE_NAME: + g_value_set_string(value, properties_get_dbus_service_name(self)); + break; + + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, properties_get_dbus_object_path(self)); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void properties_dispose (GObject *gobject) +{ + Properties *self = PROPERTIES (gobject); + + /* In dispose(), you are supposed to free all types referenced from this + * object which might themselves hold a reference to self. Generally, + * the most simple solution is to unref all members on which you own a + * reference. + */ + + /* dispose() might be called multiple times, so we must guard against + * calling g_object_unref() on an invalid GObject by setting the member + * NULL; g_clear_object() does this for us, atomically. + */ + // g_clear_object (&self->priv->an_object); + g_clear_object (&self->priv->proxy); + if(self->priv->dict_interfaces != NULL) + g_variant_unref(self->priv->dict_interfaces); + + + /* Always chain up to the parent class; there is no need to check if + * the parent class implements the dispose() virtual function: it is + * always guaranteed to do so + */ + G_OBJECT_CLASS (properties_parent_class)->dispose (gobject); +} + +static void properties_finalize (GObject *gobject) +{ + Properties *self = PROPERTIES(gobject); + + // g_free(self->priv->a_string); + + /* Always chain up to the parent class; as with dispose(), finalize() + * is guaranteed to exist on the parent's class virtual function table + */ + G_OBJECT_CLASS (properties_parent_class)->finalize (gobject); +} + +static void properties_class_init (PropertiesClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = _properties_get_property; + gobject_class->set_property = _properties_set_property; + + /* object DBusType [readwrite, construct only] */ + obj_properties[PROP_DBUS_TYPE] = + g_param_spec_string ("DBusType", + "dbus_type", + "Properties D-Bus connection type", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE); + + /* object DBusServiceName [readwrite, construct only] */ + obj_properties[PROP_DBUS_SERVICE_NAME] = + g_param_spec_string ("DBusServiceName", + "dbus_service_name", + "Properties D-Bus service name", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE); + + /* object DBusObjectPath [readwrite, construct only] */ + obj_properties[PROP_DBUS_OBJECT_PATH] = + g_param_spec_string ("DBusObjectPath", + "dbus_object_path", + "Properties D-Bus object path", + NULL /* default value */, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE); + + g_object_class_install_properties (gobject_class, + N_PROPERTIES, + obj_properties); +} + +static void properties_init (Properties *self) +{ + self->priv = properties_get_instance_private (self); + self->priv->proxy = NULL; + self->priv->dict_interfaces = NULL; + self->priv->dbus_type = NULL; + self->priv->dbus_service_name = NULL; + self->priv->dbus_object_path = NULL; +} + +static void _properties_create_gdbus_proxy(Properties *self, GError **error) +{ + if(self->priv->dbus_type && self->priv->dbus_service_name && self->priv->dbus_object_path) + { + if(g_ascii_strcasecmp(g_ascii_strdown(self->priv->dbus_type, -1), "system") == 0) + { + g_assert(system_conn != NULL); + self->priv->proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, self->priv->dbus_service_name, self->priv->dbus_object_path, PROPERTIES_DBUS_INTERFACE, NULL, error); + } + else if(g_ascii_strcasecmp(g_ascii_strdown(self->priv->dbus_type, -1), "session") == 0) + { + g_assert(session_conn != NULL); + self->priv->proxy = g_dbus_proxy_new_sync(session_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, self->priv->dbus_service_name, self->priv->dbus_object_path, PROPERTIES_DBUS_INTERFACE, NULL, error); + } + else + g_error("Invalid DBus connection type: %s", self->priv->dbus_type); + } +} + +const gchar *properties_get_dbus_type(Properties *self) +{ + g_assert(PROPERTIES_IS(self)); + g_assert(self->priv->proxy != NULL); + return self->priv->dbus_type; +} + +const gchar *properties_get_dbus_service_name(Properties *self) +{ + g_assert(PROPERTIES_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_name(self->priv->proxy); +} + +const gchar *properties_get_dbus_object_path(Properties *self) +{ + g_assert(PROPERTIES_IS(self)); + g_assert(self->priv->proxy != NULL); + return g_dbus_proxy_get_object_path(self->priv->proxy); +} + +GVariant *properties_get(Properties *self, const gchar *interface_name, const gchar *property_name, GError **error) +{ + g_assert(PROPERTIES_IS(self)); + GVariant *retVal = g_dbus_proxy_call_sync(self->priv->proxy, "Get", g_variant_new("(ss)", interface_name, property_name), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (retVal == NULL) + return NULL; + retVal = g_variant_get_child_value(retVal, 0); + retVal = g_variant_get_variant(retVal); + return retVal; +} + +void properties_set(Properties *self, const gchar *interface_name, const gchar *property_name, const GVariant *value, GError **error) +{ + g_assert(PROPERTIES_IS(self)); + g_dbus_proxy_call_sync(self->priv->proxy, "Set", g_variant_new("(ssv)", interface_name, property_name, value), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); +} + +GVariant *properties_get_all(Properties *self, const gchar *interface_name, GError **error) +{ + g_assert(PROPERTIES_IS(self)); + GVariant *retVal = g_dbus_proxy_call_sync(self->priv->proxy, "GetAll", g_variant_new("(s)", interface_name), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); + if (retVal == NULL) + return NULL; + retVal = g_variant_get_child_value(retVal, 0); + return retVal; +}
\ No newline at end of file diff --git a/src/lib/properties.h b/src/lib/properties.h new file mode 100644 index 0000000..389f042 --- /dev/null +++ b/src/lib/properties.h @@ -0,0 +1,61 @@ +#ifndef PROPERTIES_H +#define PROPERTIES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib-object.h> +/* + * Potentially, include other headers on which this header depends. + */ + +/* + * Type macros. + */ +#define PROPERTIES_TYPE (properties_get_type ()) +#define PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PROPERTIES_TYPE, Properties)) +#define PROPERTIES_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PROPERTIES_TYPE)) +#define PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PROPERTIES_TYPE, PropertiesClass)) +#define PROPERTIES_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PROPERTIES_TYPE)) +#define PROPERTIES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PROPERTIES_TYPE, PropertiesClass)) + +#define PROPERTIES_DBUS_INTERFACE "org.freedesktop.DBus.Properties" + +typedef struct _Properties Properties; +typedef struct _PropertiesPrivate PropertiesPrivate; +typedef struct _PropertiesClass PropertiesClass; + +struct _Properties { + /* Parent instance structure */ + GObject parent_instance; + + /* instance members */ + PropertiesPrivate *priv; +}; + +struct _PropertiesClass { + /* Parent class structure */ + GObjectClass parent_class; + + /* class members */ +}; + +/* used by PROPERTIES_TYPE */ +GType properties_get_type(void); + +/* + * Method definitions. + */ +const gchar *properties_get_dbus_type(Properties *self); +const gchar *properties_get_dbus_service_name(Properties *self); +const gchar *properties_get_dbus_object_path(Properties *self); +GVariant *properties_get(Properties *self, const gchar *interface_name, const gchar *property_name, GError **error); +void properties_set(Properties *self, const gchar *interface_name, const gchar *property_name, const GVariant *value, GError **error); +GVariant *properties_get_all(Properties *self, const gchar *interface_name, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* PROPERTIES_H */
\ No newline at end of file |