diff options
author | Alexander Orlenko <zxteam@gmail.com> | 2010-06-17 16:47:38 +1100 |
---|---|---|
committer | Alexander Orlenko <zxteam@gmail.com> | 2010-06-17 16:47:38 +1100 |
commit | 8ae79ab9561d7b6c1f40443bb2865269e7c793d3 (patch) | |
tree | 8ba76021acb7d8f35b1b03d6b290dc27ad2c18ba | |
parent | 19e0ebe917d933cdd3abc0d9d5cb2aed7fc63c41 (diff) | |
download | bluez-tools-8ae79ab9561d7b6c1f40443bb2865269e7c793d3.tar.gz |
some bugfixes in gen-dbus-gobject.pl && generated needed interfaces
-rwxr-xr-x[-rw-r--r--] | contrib/gen-dbus-gobject.pl | 48 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/lib/adapter.c | 435 | ||||
-rw-r--r-- | src/lib/adapter.h | 26 | ||||
-rw-r--r-- | src/lib/audio.c | 193 | ||||
-rw-r--r-- | src/lib/audio.h | 62 | ||||
-rw-r--r-- | src/lib/device.c | 449 | ||||
-rw-r--r-- | src/lib/device.h | 67 | ||||
-rw-r--r-- | src/lib/input.c | 193 | ||||
-rw-r--r-- | src/lib/input.h | 62 | ||||
-rw-r--r-- | src/lib/manager.c | 130 | ||||
-rw-r--r-- | src/lib/manager.h | 7 | ||||
-rw-r--r-- | src/lib/marshallers.c | 86 | ||||
-rw-r--r-- | src/lib/marshallers.h | 20 | ||||
-rw-r--r-- | src/lib/network.c | 217 | ||||
-rw-r--r-- | src/lib/network.h | 62 | ||||
-rw-r--r-- | src/lib/serial.c | 138 | ||||
-rw-r--r-- | src/lib/serial.h | 61 |
18 files changed, 2096 insertions, 167 deletions
diff --git a/contrib/gen-dbus-gobject.pl b/contrib/gen-dbus-gobject.pl index ca79eab..81af0e6 100644..100755 --- a/contrib/gen-dbus-gobject.pl +++ b/contrib/gen-dbus-gobject.pl @@ -245,7 +245,7 @@ EOT my $in_args = join ', ', (map "const ".get_g_type($_->{'type'}).$_->{'name'}, @{$m{'args'}});
$method_defs .=
get_g_type($m{'ret'})."{\$object}_".(join '_', (map lc $_, @a))."($obj *self, ".
- ($in_args eq '' ? "" : "$in_args, ")."GError **error = NULL);\n";
+ ($in_args eq '' ? "" : "$in_args, ")."GError **error);\n";
}
chomp $method_defs;
@@ -296,8 +296,8 @@ enum { static guint signals[LAST_SIGNAL] = {0};
{FI_SIGNALS}
-static void {\$object}_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
-static void {\$object}_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void _{\$object}_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void _{\$object}_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
{IF_SIGNALS}
{SIGNALS_HANDLERS_DEF}
@@ -311,8 +311,8 @@ static void {\$object}_class_init({\$Object}Class *klass) GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
GParamSpec *pspec;
- gobject_class->get_property = {\$object}_get_property;
- gobject_class->set_property = {\$object}_set_property;
+ gobject_class->get_property = _{\$object}_get_property;
+ gobject_class->set_property = _{\$object}_set_property;
{PROPERTIES_REGISTRATION}
@@ -324,7 +324,7 @@ static void {\$object}_class_init({\$Object}Class *klass) static void {\$object}_init({\$Object} *self)
{
- self->priv = MANAGER_GET_PRIVATE(self);
+ self->priv = {\$OBJECT}_GET_PRIVATE(self);
g_assert(conn != NULL);
@@ -354,7 +354,7 @@ static void {\$object}_post_init({\$Object} *self) }
{FI_POST_INIT}
-static void {\$object}_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+static void _{\$object}_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
{\$Object} *self = {\$OBJECT}(object);
@@ -378,13 +378,13 @@ static void {\$object}_get_property(GObject *object, guint property_id, GValue * {FI_PROPERTIES}
}
-static void {\$object}_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+static void _{\$object}_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
{\$Object} *self = {\$OBJECT}(object);
switch (property_id) {
{SET_PROPERTIES}
-
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -426,11 +426,15 @@ EOT "$method_def\n".
"{\n".
"\tg_assert(self != NULL);\n\n".
- ($m{'ret'} eq 'void' ? "" : "\t".get_g_type($m{'ret'})."ret;\n\n").
- "\tif (!dbus_g_proxy_call(self->priv->dbus_g_proxy, \"$method\", error, ".($in_args2 eq '' ? "" : "$in_args2, ")."G_TYPE_INVALID, ".($m{'ret'} eq 'void' ? "" : get_g_type_name($m{'ret'}).", &ret, ")."G_TYPE_INVALID)) {\n".
- "\t\treturn NULL;\n".
- "\t}\n\n".
- "\treturn ret;\n".
+ ($m{'ret'} eq 'void' ?
+ "\tdbus_g_proxy_call(self->priv->dbus_g_proxy, \"$method\", error, ".($in_args2 eq '' ? "" : "$in_args2, ")."G_TYPE_INVALID, G_TYPE_INVALID);\n"
+ :
+ "\t".get_g_type($m{'ret'})."ret;\n\n".
+ "\tif (!dbus_g_proxy_call(self->priv->dbus_g_proxy, \"$method\", error, ".($in_args2 eq '' ? "" : "$in_args2, ")."G_TYPE_INVALID, ".($m{'ret'} eq 'void' ? "" : get_g_type_name($m{'ret'}).", &ret, ")."G_TYPE_INVALID)) {\n".
+ "\t\treturn NULL;\n".
+ "\t}\n\n".
+ "\treturn ret;\n"
+ ).
"}\n\n";
}
$methods =~ s/\s+$//s;
@@ -446,7 +450,8 @@ EOT my $enum = join '_', (map uc $_, @a);
my $handler_name = (join '_', (map lc $_, @a))."_handler";
- my $handler = "static void $handler_name(DBusGProxy *dbus_g_proxy, ".(join ', ', map("const ".get_g_type($_->{'type'}).$_->{'name'}, @{$s{'args'}})).", gpointer data)";
+ my $in_args = join ', ', map("const ".get_g_type($_->{'type'}).$_->{'name'}, @{$s{'args'}});
+ my $handler = "static void $handler_name(DBusGProxy *dbus_g_proxy, ".($in_args eq '' ? "" : "$in_args, ")."gpointer data)";
$signals_registration .=
"\tsignals[$enum] = g_signal_new(\"$signal\",\n".
@@ -471,9 +476,10 @@ EOT die "unknown signal arguments: $arg_t\n";
}
+ my $in_args2 = join ', ', (map get_g_type_name($_->{'type'}), @{$s{'args'}});
$signals_connection .=
"\t/* $s{'decl'} */\n".
- "\tdbus_g_proxy_add_signal(self->priv->dbus_g_proxy, \"$signal\", ".(join ', ', (map get_g_type_name($_->{'type'}), @{$s{'args'}})).", G_TYPE_INVALID);\n".
+ "\tdbus_g_proxy_add_signal(self->priv->dbus_g_proxy, \"$signal\", ".($in_args2 eq '' ? "" : "$in_args2, ")."G_TYPE_INVALID);\n".
"\tdbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, \"$signal\", G_CALLBACK($handler_name), self, NULL);\n\n";
my $args = join ', ', map($_->{'name'}, @{$s{'args'}});
@@ -535,7 +541,7 @@ EOT $properties_registration .= "\tpspec = g_param_spec_boxed(\"$property\", NULL, NULL, G_TYPE_PTR_ARRAY, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
$get_properties .= "\t\tg_value_set_boxed(value, g_value_dup_boxed(g_hash_table_lookup(properties, \"$property\")));\n";
} elsif ($p{'type'} eq 'uint32') {
- $properties_registration .= "\tpspec = g_param_spec_uint(\"$property\", NULL, NULL, 0, 4294967295, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
+ $properties_registration .= "\tpspec = g_param_spec_uint(\"$property\", NULL, NULL, 0, 65535, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
$get_properties .= "\t\tg_value_set_uint(value, g_value_get_uint(g_hash_table_lookup(properties, \"$property\")));\n";
} elsif ($p{'type'} eq 'boolean') {
$properties_registration .= "\tpspec = g_param_spec_boolean(\"$property\", NULL, NULL, FALSE, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
@@ -560,7 +566,7 @@ EOT "\t\tbreak;\n\n";
}
}
- $enum_properties =~ s/^\t(.+?), (\/\* .+? \*\/)\s+$/$1 $2/s;
+ $enum_properties =~ s/^\t(.+), (\/\* .+? \*\/)\s+$/$1 $2/s;
$properties_registration =~ s/^\t(.+?)\s+$/$1/s;
$get_properties =~ s/^\t(.+?)\s+$/$1/s;
$set_properties =~ s/^\t(.+?)\s+$/$1/s;
@@ -576,12 +582,12 @@ EOT if (scalar keys %{$node->{$intf}{'signals'}} > 0) {
$output =~ s/\{IF_SIGNALS\}\s+(.+?)\s+\{FI_SIGNALS\}/$1/gs;
} else {
- $output =~ s/\s+\{IF_SIGNALS\}.+?\{FI_SIGNALS\}\s+/\n\n/gs;
+ $output =~ s/\s+\{IF_SIGNALS\}.+?\{FI_SIGNALS\}//gs;
}
if (scalar keys %{$node->{$intf}{'properties'}} > 0) {
$output =~ s/\{IF_PROPERTIES\}\s+(.+?)\s+\{FI_PROPERTIES\}/$1/gs;
} else {
- $output =~ s/\s+\{IF_PROPERTIES\}.+?\{FI_PROPERTIES\}\s+/\n\n/gs;
+ $output =~ s/\s+\{IF_PROPERTIES\}.+?\{FI_PROPERTIES\}//gs;
}
$output =~ s/{BLUEZ_DBUS_OBJECT_DEFS}/$bluez_dbus_object_defs/;
$output =~ s/{ENUM_SIGNALS}/$enum_signals/;
@@ -601,7 +607,7 @@ EOT # Some formatting fixes
$output =~ s/\s+?(\t*\})/\n$1/g;
$output =~ s/(switch \(\w+\) \{\n)\s+?(\t+default:)/$1$2/s;
- $output =~ s/\s+$/\n\n/;
+ $output =~ s/\s+$/\n\n/s;
return $output;
}
diff --git a/src/Makefile.am b/src/Makefile.am index d3284c3..406fda6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,12 @@ lib/marshallers.c: lib/marshallers.list lib_sources = lib/marshallers.c lib/marshallers.h \ lib/dbus-common.c lib/dbus-common.h \ lib/adapter.c lib/adapter.h \ - lib/manager.c lib/manager.h + lib/audio.c lib/audio.h \ + lib/device.c lib/device.h \ + lib/input.c lib/input.h \ + lib/manager.c lib/manager.h \ + lib/network.c lib/network.h \ + lib/serial.c lib/serial.h bin_PROGRAMS = bt-monitor bt_monitor_SOURCES = $(lib_sources) bt-monitor.c diff --git a/src/lib/adapter.c b/src/lib/adapter.c index b3ea624..8d877d6 100644 --- a/src/lib/adapter.c +++ b/src/lib/adapter.c @@ -44,38 +44,38 @@ enum { PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ PROP_ADDRESS, /* readonly */ - PROP_NAME, /* readwrite */ PROP_CLASS, /* readonly */ - PROP_POWERED, /* readwrite */ + PROP_DEVICES, /* readonly */ PROP_DISCOVERABLE, /* readwrite */ - PROP_PAIRABLE, /* readwrite */ - PROP_PAIRABLE_TIMEOUT, /* readwrite */ PROP_DISCOVERABLE_TIMEOUT, /* readwrite */ PROP_DISCOVERING, /* readonly */ - PROP_DEVICES, /* readonly */ + PROP_NAME, /* readwrite */ + PROP_PAIRABLE, /* readwrite */ + PROP_PAIREABLE_TIMEOUT, /* readwrite */ + PROP_POWERED, /* readwrite */ PROP_UUIDS /* readonly */ }; enum { - PROPERTY_CHANGED, - DEVICE_FOUND, - DEVICE_DISAPPEARED, DEVICE_CREATED, + DEVICE_DISAPPEARED, + DEVICE_FOUND, DEVICE_REMOVED, + PROPERTY_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; -static void adapter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void adapter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +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); -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *property, const GValue *value, gpointer data); -static void device_found_handler(DBusGProxy *dbus_g_proxy, const gchar *address, const GHashTable *properties, gpointer data); +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_created_handler(DBusGProxy *dbus_g_proxy, const gchar *path, gpointer data); -static void device_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *path, gpointer data); +static void device_found_handler(DBusGProxy *dbus_g_proxy, const gchar *address, const 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_class_init(AdapterClass *klass) { @@ -85,56 +85,92 @@ static void adapter_class_init(AdapterClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GParamSpec *pspec; - gobject_class->set_property = adapter_set_property; - gobject_class->get_property = adapter_get_property; + 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_CONSTRUCT_ONLY | G_PARAM_READWRITE); + 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", "address", "Adapter address", NULL, G_PARAM_READABLE); + pspec = g_param_spec_string("Address", NULL, NULL, NULL, G_PARAM_READABLE); g_object_class_install_property(gobject_class, PROP_ADDRESS, pspec); - /* string Name [readwrite] */ - pspec = g_param_spec_string("Name", "name", "Adapter name", NULL, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_NAME, pspec); - /* uint32 Class [readonly] */ - pspec = g_param_spec_uint("Class", "class", "Adapter bluetooth class", 0, 4294967295, 0, G_PARAM_READABLE); + pspec = g_param_spec_uint("Class", NULL, NULL, 0, 65535, 0, G_PARAM_READABLE); g_object_class_install_property(gobject_class, PROP_CLASS, pspec); - /* boolean Powered [readwrite] */ - pspec = g_param_spec_boolean("Powered", "powered", "Adapter powered state", FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_POWERED, 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", "discoverable", "Adapter discoverable state", FALSE, G_PARAM_READWRITE); + pspec = g_param_spec_boolean("Discoverable", NULL, NULL, FALSE, G_PARAM_READWRITE); g_object_class_install_property(gobject_class, PROP_DISCOVERABLE, pspec); - /* boolean Pairable [readwrite] */ - pspec = g_param_spec_boolean("Pairable", "pairable", "Adapter pairable state", FALSE, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_PAIRABLE, pspec); - - /* uint32 PaireableTimeout [readwrite] */ - pspec = g_param_spec_uint("PaireableTimeout", "paireable_timeout", "Adapter paireable timeout", 0, 4294967295, 0, G_PARAM_READWRITE); - g_object_class_install_property(gobject_class, PROP_PAIRABLE_TIMEOUT, pspec); - /* uint32 DiscoverableTimeout [readwrite] */ - pspec = g_param_spec_uint("DiscoverableTimeout", "discoverable_timeout", "Adapter discoverable timeout", 0, 4294967295, 0, G_PARAM_READWRITE); + pspec = g_param_spec_uint("DiscoverableTimeout", NULL, NULL, 0, 65535, 0, G_PARAM_READWRITE); g_object_class_install_property(gobject_class, PROP_DISCOVERABLE_TIMEOUT, pspec); /* boolean Discovering [readonly] */ - pspec = g_param_spec_boolean("Discovering", "discovering", "Adapter discover mode state", FALSE, G_PARAM_READABLE); + pspec = g_param_spec_boolean("Discovering", NULL, NULL, FALSE, G_PARAM_READABLE); g_object_class_install_property(gobject_class, PROP_DISCOVERING, pspec); - /* array{object} Devices [readonly] */ - pspec = g_param_spec_boxed("Devices", "devices", "List of added devices", G_TYPE_PTR_ARRAY, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, PROP_DEVICES, 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 PaireableTimeout [readwrite] */ + pspec = g_param_spec_uint("PaireableTimeout", NULL, NULL, 0, 65535, 0, G_PARAM_READWRITE); + g_object_class_install_property(gobject_class, PROP_PAIREABLE_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", "uuids", "List of available UUIDs", G_TYPE_PTR_ARRAY, G_PARAM_READABLE); + pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_PTR_ARRAY, 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_bluez_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); + + 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_bluez_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); } static void adapter_init(Adapter *self) @@ -146,60 +182,175 @@ static void adapter_init(Adapter *self) static void adapter_post_init(Adapter *self) { - /* DBUS signals connection */ + g_assert(self->priv->dbus_g_proxy != 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); + /* DBUS signals connection */ - /* DeviceFound(string address, dict values) */ - dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "DeviceFound", G_TYPE_STRING, dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "DeviceFound", G_CALLBACK(device_found_handler), self, NULL); + /* 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); - /* 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); + /* 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); } -static void adapter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +static void _adapter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { Adapter *self = ADAPTER(object); + GHashTable *properties = adapter_get_properties(self, NULL); + if (properties == NULL) { + return; + } + switch (property_id) { case PROP_DBUS_OBJECT_PATH: - { - const gchar *dbus_object_path = g_value_get_string(value); - g_assert(dbus_object_path != NULL); - g_assert(self->priv->dbus_g_proxy == NULL); - self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_ADAPTER_INTERFACE); - adapter_post_init(self); - } + g_value_set_string(value, g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy))); + break; + + case PROP_ADDRESS: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Address"))); + break; + + case PROP_CLASS: + g_value_set_uint(value, g_value_get_uint(g_hash_table_lookup(properties, "Class"))); + break; + + case PROP_DEVICES: + g_value_set_boxed(value, g_value_dup_boxed(g_hash_table_lookup(properties, "Devices"))); + break; + + case PROP_DISCOVERABLE: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Discoverable"))); + break; + + case PROP_DISCOVERABLE_TIMEOUT: + g_value_set_uint(value, g_value_get_uint(g_hash_table_lookup(properties, "DiscoverableTimeout"))); + break; + + case PROP_DISCOVERING: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Discovering"))); + break; + + case PROP_NAME: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Name"))); + break; + + case PROP_PAIRABLE: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Pairable"))); + break; + + case PROP_PAIREABLE_TIMEOUT: + g_value_set_uint(value, g_value_get_uint(g_hash_table_lookup(properties, "PaireableTimeout"))); + break; + + case PROP_POWERED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Powered"))); + break; + + case PROP_UUIDS: + g_value_set_boxed(value, g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs"))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } + + g_hash_table_unref(properties); } -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) { Adapter *self = ADAPTER(object); switch (property_id) { case PROP_DBUS_OBJECT_PATH: { - // TODO: check pointers - gchar *object_path = g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy)); - g_value_set_string(value, object_path); + const gchar *dbus_object_path = g_value_get_string(value); + g_assert(dbus_object_path != NULL); + g_assert(self->priv->dbus_g_proxy == NULL); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_ADAPTER_INTERFACE); + adapter_post_init(self); + } + break; + + case PROP_DISCOVERABLE: + { + GError *error = NULL; + adapter_set_property(self, "Discoverable", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_DISCOVERABLE_TIMEOUT: + { + GError *error = NULL; + adapter_set_property(self, "DiscoverableTimeout", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_NAME: + { + GError *error = NULL; + adapter_set_property(self, "Name", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_PAIRABLE: + { + GError *error = NULL; + adapter_set_property(self, "Pairable", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_PAIREABLE_TIMEOUT: + { + GError *error = NULL; + adapter_set_property(self, "PaireableTimeout", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_POWERED: + { + GError *error = NULL; + adapter_set_property(self, "Powered", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } } break; @@ -209,10 +360,164 @@ static void adapter_get_property(GObject *object, guint property_id, GValue *val } } +/* Methods */ + +/* void CancelDeviceCreation(string address) */ +void adapter_cancel_device_creation(Adapter *self, const gchar *address, GError **error) +{ + g_assert(self != NULL); + + 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(self != NULL); + + gchar *ret; + + if (!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 NULL; + } + + return ret; +} + +/* object CreatePairedDevice(string address, object agent, string capability) */ +gchar *adapter_create_paired_device(Adapter *self, const gchar *address, const gchar *agent, const gchar *capability, GError **error) +{ + g_assert(self != NULL); + + gchar *ret; + + if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreatePairedDevice", error, G_TYPE_STRING, address, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_STRING, capability, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID)) { + return NULL; + } + + return ret; +} + +/* object FindDevice(string address) */ +gchar *adapter_find_device(Adapter *self, const gchar *address, GError **error) +{ + g_assert(self != NULL); + + gchar *ret; + + if (!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 NULL; + } + + return ret; +} + +/* dict GetProperties() */ +GHashTable *adapter_get_properties(Adapter *self, GError **error) +{ + g_assert(self != NULL); + + GHashTable *ret; + + if (!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 NULL; + } + + return ret; +} + +/* void RegisterAgent(object agent, string capability) */ +void adapter_register_agent(Adapter *self, const gchar *agent, const gchar *capability, GError **error) +{ + g_assert(self != NULL); + + 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); +} + +/* void ReleaseSession() */ +void adapter_release_session(Adapter *self, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "ReleaseSession", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void RemoveDevice(object device) */ +void adapter_remove_device(Adapter *self, const gchar *device, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoveDevice", error, DBUS_TYPE_G_OBJECT_PATH, device, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void RequestSession() */ +void adapter_request_session(Adapter *self, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "RequestSession", error, 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(self != NULL); + + 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); +} + +/* void StartDiscovery() */ +void adapter_start_discovery(Adapter *self, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "StartDiscovery", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void StopDiscovery() */ +void adapter_stop_discovery(Adapter *self, GError **error) +{ + g_assert(self != NULL); + + 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(self != NULL); + + 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 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, const GHashTable *values, gpointer data) +{ + Adapter *self = ADAPTER(data); + g_signal_emit(self, signals[DEVICE_FOUND], 0, address, values); +} + +static void device_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *device, gpointer data) +{ + Adapter *self = ADAPTER(data); + g_signal_emit(self, signals[DEVICE_REMOVED], 0, device); +} + static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) { Adapter *self = ADAPTER(data); - g_print("property changed\n"); - //g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); + g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); } + diff --git a/src/lib/adapter.h b/src/lib/adapter.h index 2824f3d..3b15e4d 100644 --- a/src/lib/adapter.h +++ b/src/lib/adapter.h @@ -54,17 +54,19 @@ struct _AdapterClass { /* * Method definitions */ -gboolean adapter_get_properties(Adapter *self, GError **error, GHashTable **properties); -gboolean adapter_request_session(Adapter *self, GError **error); -gboolean adapter_release_session(Adapter *self, GError **error); -gboolean adapter_start_discovery(Adapter *self, GError **error); -gboolean adapter_stop_discovery(Adapter *self, GError **error); -gboolean adapter_find_device(Adapter *self, GError **error, const gchar *device_address, gchar **device_path); -gboolean adapter_create_device(Adapter *self, GError **error, const gchar *device_address, gchar **device_path); -gboolean adapter_create_paired_device(Adapter *self, GError **error, const gchar *device_address, const gchar *agent_path, const gchar *agent_capability, gchar **device_path); -gboolean adapter_cancel_device_creation(Adapter *self, GError **error, const gchar *device_address); -gboolean adapter_remove_device(Adapter *self, GError **error, const gchar *device_path); -gboolean adapter_register_agent(Adapter *self, GError **error, const gchar *agent_path, const gchar *agent_capability); -gboolean adapter_unregister_agent(Adapter *self, GError **error, const gchar *agent_path); +void adapter_cancel_device_creation(Adapter *self, const gchar *address, GError **error); +gchar *adapter_create_device(Adapter *self, const gchar *address, GError **error); +gchar *adapter_create_paired_device(Adapter *self, const gchar *address, const gchar *agent, const gchar *capability, 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); +void adapter_release_session(Adapter *self, GError **error); +void adapter_remove_device(Adapter *self, const gchar *device, GError **error); +void adapter_request_session(Adapter *self, 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); #endif /* __ADAPTER_H */ + diff --git a/src/lib/audio.c b/src/lib/audio.c new file mode 100644 index 0000000..aad9d1f --- /dev/null +++ b/src/lib/audio.c @@ -0,0 +1,193 @@ +/* + * + * 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 "dbus-common.h" +#include "marshallers.h" +#include "audio.h" + +#define BLUEZ_DBUS_AUDIO_INTERFACE "org.bluez.Audio" + +#define AUDIO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), AUDIO_TYPE, AudioPrivate)) + +struct _AudioPrivate { + DBusGProxy *dbus_g_proxy; +}; + +G_DEFINE_TYPE(Audio, audio, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ + PROP_STATE /* readonly */ +}; + +enum { + PROPERTY_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +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); + +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); + +static void audio_class_init(AudioClass *klass) +{ + g_type_class_add_private(klass, sizeof(AudioPrivate)); + + /* Properties registration */ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + 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_bluez_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); + + g_assert(conn != NULL); +} + +static void audio_post_init(Audio *self) +{ + g_assert(self->priv->dbus_g_proxy != NULL); + + /* 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); +} + +static void _audio_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Audio *self = AUDIO(object); + + GHashTable *properties = audio_get_properties(self, NULL); + if (properties == NULL) { + return; + } + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy))); + break; + + case PROP_STATE: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "State"))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + g_hash_table_unref(properties); +} + +static void _audio_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Audio *self = AUDIO(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + { + const gchar *dbus_object_path = g_value_get_string(value); + g_assert(dbus_object_path != NULL); + g_assert(self->priv->dbus_g_proxy == NULL); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_AUDIO_INTERFACE); + audio_post_init(self); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* Methods */ + +/* void Connect() */ +void audio_connect(Audio *self, GError **error) +{ + g_assert(self != NULL); + + 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(self != NULL); + + 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(self != NULL); + + GHashTable *ret; + + if (!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 NULL; + } + + return ret; +} + +/* Signals handlers */ +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +{ + Audio *self = AUDIO(data); + g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); +} + diff --git a/src/lib/audio.h b/src/lib/audio.h new file mode 100644 index 0000000..ac0c1c4 --- /dev/null +++ b/src/lib/audio.h @@ -0,0 +1,62 @@ +/* + * + * 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> + +/* + * 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; +}; + +/* + * Method definitions + */ +void audio_connect(Audio *self, GError **error); +void audio_disconnect(Audio *self, GError **error); +GHashTable *audio_get_properties(Audio *self, GError **error); + +#endif /* __AUDIO_H */ + diff --git a/src/lib/device.c b/src/lib/device.c new file mode 100644 index 0000000..00560f2 --- /dev/null +++ b/src/lib/device.c @@ -0,0 +1,449 @@ +/* + * + * 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 "dbus-common.h" +#include "marshallers.h" +#include "device.h" + +#define BLUEZ_DBUS_DEVICE_INTERFACE "org.bluez.Device" + +#define DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), DEVICE_TYPE, DevicePrivate)) + +struct _DevicePrivate { + DBusGProxy *dbus_g_proxy; +}; + +G_DEFINE_TYPE(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_NODES, /* readonly */ + PROP_PAIRED, /* readonly */ + PROP_TRUSTED, /* readwrite */ + PROP_UUIDS /* readonly */ +}; + +enum { + DISCONNECT_REQUESTED, + NODE_CREATED, + NODE_REMOVED, + PROPERTY_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +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); + +static void disconnect_requested_handler(DBusGProxy *dbus_g_proxy, gpointer data); +static void node_created_handler(DBusGProxy *dbus_g_proxy, const gchar *node, gpointer data); +static void node_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *node, gpointer data); +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); + +static void device_class_init(DeviceClass *klass) +{ + g_type_class_add_private(klass, sizeof(DevicePrivate)); + + /* Properties registration */ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + 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); + 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, 65535, 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); + + /* array{object} Nodes [readonly] */ + pspec = g_param_spec_boxed("Nodes", NULL, NULL, G_TYPE_PTR_ARRAY, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_NODES, 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); + + /* 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_PTR_ARRAY, 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[NODE_CREATED] = g_signal_new("NodeCreated", + 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[NODE_REMOVED] = g_signal_new("NodeRemoved", + 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_bluez_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); +} + +static void device_init(Device *self) +{ + self->priv = DEVICE_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void device_post_init(Device *self) +{ + g_assert(self->priv->dbus_g_proxy != NULL); + + /* 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); + + /* NodeCreated(object node) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "NodeCreated", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "NodeCreated", G_CALLBACK(node_created_handler), self, NULL); + + /* NodeRemoved(object node) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "NodeRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "NodeRemoved", G_CALLBACK(node_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); +} + +static void _device_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Device *self = DEVICE(object); + + GHashTable *properties = device_get_properties(self, NULL); + if (properties == NULL) { + return; + } + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy))); + break; + + case PROP_ADAPTER: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Adapter"))); + break; + + case PROP_ADDRESS: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Address"))); + break; + + case PROP_ALIAS: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Alias"))); + break; + + case PROP_BLOCKED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Blocked"))); + break; + + case PROP_CLASS: + g_value_set_uint(value, g_value_get_uint(g_hash_table_lookup(properties, "Class"))); + break; + + case PROP_CONNECTED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Connected"))); + break; + + case PROP_ICON: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Icon"))); + break; + + case PROP_LEGACY_PAIRING: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "LegacyPairing"))); + break; + + case PROP_NAME: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Name"))); + break; + + case PROP_NODES: + g_value_set_boxed(value, g_value_dup_boxed(g_hash_table_lookup(properties, "Nodes"))); + break; + + case PROP_PAIRED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Paired"))); + break; + + case PROP_TRUSTED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Trusted"))); + break; + + case PROP_UUIDS: + g_value_set_boxed(value, g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs"))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + g_hash_table_unref(properties); +} + +static void _device_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Device *self = DEVICE(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + { + const gchar *dbus_object_path = g_value_get_string(value); + g_assert(dbus_object_path != NULL); + g_assert(self->priv->dbus_g_proxy == NULL); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_DEVICE_INTERFACE); + device_post_init(self); + } + break; + + case PROP_ALIAS: + { + GError *error = NULL; + device_set_property(self, "Alias", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_BLOCKED: + { + GError *error = NULL; + device_set_property(self, "Blocked", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + case PROP_TRUSTED: + { + GError *error = NULL; + device_set_property(self, "Trusted", value, &error); + if (error != NULL) { + g_print("%s: %s\n", g_get_prgname(), error->message); + g_error_free(error); + } + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* Methods */ + +/* void CancelDiscovery() */ +void device_cancel_discovery(Device *self, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "CancelDiscovery", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* object CreateNode(string uuid) */ +gchar *device_create_node(Device *self, const gchar *uuid, GError **error) +{ + g_assert(self != NULL); + + gchar *ret; + + if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateNode", error, G_TYPE_STRING, uuid, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID)) { + return NULL; + } + + return ret; +} + +/* void Disconnect() */ +void device_disconnect(Device *self, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* dict DiscoverServices(string pattern) */ +GHashTable *device_discover_services(Device *self, const gchar *pattern, GError **error) +{ + g_assert(self != NULL); + + GHashTable *ret; + + if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "DiscoverServices", error, G_TYPE_STRING, pattern, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID)) { + return NULL; + } + + return ret; +} + +/* dict GetProperties() */ +GHashTable *device_get_properties(Device *self, GError **error) +{ + g_assert(self != NULL); + + GHashTable *ret; + + if (!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 NULL; + } + + return ret; +} + +/* array{object} ListNodes() */ +GPtrArray *device_list_nodes(Device *self, GError **error) +{ + g_assert(self != NULL); + + GPtrArray *ret; + + if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "ListNodes", error, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_ARRAY, &ret, G_TYPE_INVALID)) { + return NULL; + } + + return ret; +} + +/* void RemoveNode(object node) */ +void device_remove_node(Device *self, const gchar *node, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoveNode", error, DBUS_TYPE_G_OBJECT_PATH, node, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void SetProperty(string name, variant value) */ +void device_set_property(Device *self, const gchar *name, const GValue *value, GError **error) +{ + g_assert(self != NULL); + + 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); +} + +/* 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 node_created_handler(DBusGProxy *dbus_g_proxy, const gchar *node, gpointer data) +{ + Device *self = DEVICE(data); + g_signal_emit(self, signals[NODE_CREATED], 0, node); +} + +static void node_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *node, gpointer data) +{ + Device *self = DEVICE(data); + g_signal_emit(self, signals[NODE_REMOVED], 0, node); +} + +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +{ + Device *self = DEVICE(data); + g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); +} + diff --git a/src/lib/device.h b/src/lib/device.h new file mode 100644 index 0000000..30586d0 --- /dev/null +++ b/src/lib/device.h @@ -0,0 +1,67 @@ +/* + * + * 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 __DEVICE_H +#define __DEVICE_H + +#include <glib-object.h> + +/* + * Type macros + */ +#define DEVICE_TYPE (device_get_type()) +#define DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), DEVICE_TYPE, Device)) +#define DEVICE_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), DEVICE_TYPE)) +#define DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), DEVICE_TYPE, DeviceClass)) +#define DEVICE_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), DEVICE_TYPE)) +#define DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), DEVICE_TYPE, DeviceClass)) + +typedef struct _Device Device; +typedef struct _DeviceClass DeviceClass; +typedef struct _DevicePrivate DevicePrivate; + +struct _Device { + GObject parent_instance; + + /*< private >*/ + DevicePrivate *priv; +}; + +struct _DeviceClass { + GObjectClass parent_class; +}; + +/* + * Method definitions + */ +void device_cancel_discovery(Device *self, GError **error); +gchar *device_create_node(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); +GPtrArray *device_list_nodes(Device *self, GError **error); +void device_remove_node(Device *self, const gchar *node, GError **error); +void device_set_property(Device *self, const gchar *name, const GValue *value, GError **error); + +#endif /* __DEVICE_H */ + diff --git a/src/lib/input.c b/src/lib/input.c new file mode 100644 index 0000000..6a4cd89 --- /dev/null +++ b/src/lib/input.c @@ -0,0 +1,193 @@ +/* + * + * 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 "dbus-common.h" +#include "marshallers.h" +#include "input.h" + +#define BLUEZ_DBUS_INPUT_INTERFACE "org.bluez.Input" + +#define INPUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), INPUT_TYPE, InputPrivate)) + +struct _InputPrivate { + DBusGProxy *dbus_g_proxy; +}; + +G_DEFINE_TYPE(Input, input, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ + PROP_CONNECTED /* readonly */ +}; + +enum { + PROPERTY_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +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); + +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); + +static void input_class_init(InputClass *klass) +{ + g_type_class_add_private(klass, sizeof(InputPrivate)); + + /* Properties registration */ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + 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_bluez_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); + + g_assert(conn != NULL); +} + +static void input_post_init(Input *self) +{ + g_assert(self->priv->dbus_g_proxy != NULL); + + /* 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); +} + +static void _input_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Input *self = INPUT(object); + + GHashTable *properties = input_get_properties(self, NULL); + if (properties == NULL) { + return; + } + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy))); + break; + + case PROP_CONNECTED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Connected"))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + g_hash_table_unref(properties); +} + +static void _input_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Input *self = INPUT(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + { + const gchar *dbus_object_path = g_value_get_string(value); + g_assert(dbus_object_path != NULL); + g_assert(self->priv->dbus_g_proxy == NULL); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_INPUT_INTERFACE); + input_post_init(self); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* Methods */ + +/* void Connect() */ +void input_connect(Input *self, GError **error) +{ + g_assert(self != NULL); + + 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(self != NULL); + + 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(self != NULL); + + GHashTable *ret; + + if (!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 NULL; + } + + return ret; +} + +/* Signals handlers */ +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +{ + Input *self = INPUT(data); + g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); +} + diff --git a/src/lib/input.h b/src/lib/input.h new file mode 100644 index 0000000..47f30b0 --- /dev/null +++ b/src/lib/input.h @@ -0,0 +1,62 @@ +/* + * + * 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> + +/* + * 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; +}; + +/* + * Method definitions + */ +void input_connect(Input *self, GError **error); +void input_disconnect(Input *self, GError **error); +GHashTable *input_get_properties(Input *self, GError **error); + +#endif /* __INPUT_H */ + diff --git a/src/lib/manager.c b/src/lib/manager.c index 2bca804..af7382c 100644 --- a/src/lib/manager.c +++ b/src/lib/manager.c @@ -47,23 +47,23 @@ enum { }; enum { - PROPERTY_CHANGED, ADAPTER_ADDED, ADAPTER_REMOVED, DEFAULT_ADAPTER_CHANGED, + PROPERTY_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; -static void manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +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); -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *property, const GValue *value, gpointer data); -static void adapter_added_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter_path, gpointer data); -static void adapter_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter_path, gpointer data); -static void default_adapter_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter_path, gpointer data); +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_class_init(ManagerClass *klass) { @@ -73,21 +73,14 @@ static void manager_class_init(ManagerClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GParamSpec *pspec; - gobject_class->set_property = manager_set_property; - gobject_class->get_property = manager_get_property; + gobject_class->get_property = _manager_get_property; + gobject_class->set_property = _manager_set_property; /* array{object} Adapters [readonly] */ - pspec = g_param_spec_boxed("Adapters", "adapters", "List of adapters", G_TYPE_PTR_ARRAY, G_PARAM_READABLE); + 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[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_bluez_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); - 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, @@ -108,6 +101,13 @@ static void manager_class_init(ManagerClass *klass) 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_bluez_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); } static void manager_init(Manager *self) @@ -118,11 +118,9 @@ static void manager_init(Manager *self) self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_MANAGER_PATH, BLUEZ_DBUS_MANAGER_INTERFACE); - /* DBUS signals connection */ + g_assert(self->priv->dbus_g_proxy != 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); + /* 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); @@ -135,25 +133,18 @@ static void manager_init(Manager *self) /* 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); -} -static void manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - Manager *self = MANAGER(object); - - switch (property_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - break; - } + /* 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); } -static void manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +static void _manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { Manager *self = MANAGER(object); - GHashTable *properties; - if (!manager_get_properties(self, NULL, &properties)) { + GHashTable *properties = manager_get_properties(self, NULL); + if (properties == NULL) { return; } @@ -170,74 +161,83 @@ static void manager_get_property(GObject *object, guint property_id, GValue *val g_hash_table_unref(properties); } +static void _manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Manager *self = MANAGER(object); + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + /* Methods */ -/* dict GetProperties() - * - * Properties: - * array{object} Adapters - * - */ -gboolean manager_get_properties(Manager *self, GError **error, GHashTable **properties) +/* object DefaultAdapter() */ +gchar *manager_default_adapter(Manager *self, GError **error) { g_assert(self != NULL); - if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), properties, G_TYPE_INVALID)) { - return FALSE; + gchar *ret; + + if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "DefaultAdapter", error, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID)) { + return NULL; } - return TRUE; + return ret; } -/* object DefaultAdapter() */ -gboolean manager_get_default_adapter(Manager *self, GError **error, gchar **adapter_path) +/* object FindAdapter(string pattern) */ +gchar *manager_find_adapter(Manager *self, const gchar *pattern, GError **error) { g_assert(self != NULL); - if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "DefaultAdapter", error, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, adapter_path, G_TYPE_INVALID)) { - return FALSE; + gchar *ret; + + if (!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 NULL; } - return TRUE; + return ret; } -/* object FindAdapter(string pattern) */ -gboolean manager_find_adapter(Manager *self, GError **error, const gchar *adapter_name, gchar **adapter_path) +/* dict GetProperties() */ +GHashTable *manager_get_properties(Manager *self, GError **error) { g_assert(self != NULL); - if (adapter_name == NULL) { - return manager_get_default_adapter(self, error, adapter_path); - } + GHashTable *ret; - if (!dbus_g_proxy_call(self->priv->dbus_g_proxy, "FindAdapter", error, G_TYPE_STRING, adapter_name, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, adapter_path, G_TYPE_INVALID)) { - return FALSE; + if (!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 NULL; } - return TRUE; + return ret; } /* Signals handlers */ -static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +static void adapter_added_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data) { Manager *self = MANAGER(data); - g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); + g_signal_emit(self, signals[ADAPTER_ADDED], 0, adapter); } -static void adapter_added_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter_path, gpointer data) +static void adapter_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data) { Manager *self = MANAGER(data); - g_signal_emit(self, signals[ADAPTER_ADDED], 0, adapter_path); + g_signal_emit(self, signals[ADAPTER_REMOVED], 0, adapter); } -static void adapter_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter_path, gpointer data) +static void default_adapter_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter, gpointer data) { Manager *self = MANAGER(data); - g_signal_emit(self, signals[ADAPTER_REMOVED], 0, adapter_path); + g_signal_emit(self, signals[DEFAULT_ADAPTER_CHANGED], 0, adapter); } -static void default_adapter_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *adapter_path, gpointer data) +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) { Manager *self = MANAGER(data); - g_signal_emit(self, signals[DEFAULT_ADAPTER_CHANGED], 0, adapter_path); + g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); } + diff --git a/src/lib/manager.h b/src/lib/manager.h index 8d9f175..8ebb7a4 100644 --- a/src/lib/manager.h +++ b/src/lib/manager.h @@ -54,8 +54,9 @@ struct _ManagerClass { /* * Method definitions */ -gboolean manager_get_properties(Manager *self, GError **error, GHashTable **properties); -gboolean manager_get_default_adapter(Manager *self, GError **error, gchar **adapter_path); -gboolean manager_find_adapter(Manager *self, GError **error, const gchar *adapter_name, gchar **adapter_path); +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); #endif /* __MANAGER_H */ + diff --git a/src/lib/marshallers.c b/src/lib/marshallers.c new file mode 100644 index 0000000..0d4eca4 --- /dev/null +++ b/src/lib/marshallers.c @@ -0,0 +1,86 @@ + +#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:1) */ +void +g_cclosure_bluez_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); +} + diff --git a/src/lib/marshallers.h b/src/lib/marshallers.h new file mode 100644 index 0000000..50093ba --- /dev/null +++ b/src/lib/marshallers.h @@ -0,0 +1,20 @@ + +#ifndef __g_cclosure_bluez_marshal_MARSHAL_H__ +#define __g_cclosure_bluez_marshal_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +/* VOID:STRING,BOXED (lib/marshallers.list:1) */ +extern void g_cclosure_bluez_marshal_VOID__STRING_BOXED (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_bluez_marshal_MARSHAL_H__ */ + diff --git a/src/lib/network.c b/src/lib/network.c new file mode 100644 index 0000000..a67e7ef --- /dev/null +++ b/src/lib/network.c @@ -0,0 +1,217 @@ +/* + * + * 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 "dbus-common.h" +#include "marshallers.h" +#include "network.h" + +#define BLUEZ_DBUS_NETWORK_INTERFACE "org.bluez.Network" + +#define NETWORK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), NETWORK_TYPE, NetworkPrivate)) + +struct _NetworkPrivate { + DBusGProxy *dbus_g_proxy; +}; + +G_DEFINE_TYPE(Network, network, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ + PROP_CONNECTED, /* readonly */ + PROP_INTERFACE, /* readonly */ + PROP_UUID /* readonly */ +}; + +enum { + PROPERTY_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +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); + +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data); + +static void network_class_init(NetworkClass *klass) +{ + g_type_class_add_private(klass, sizeof(NetworkPrivate)); + + /* Properties registration */ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + 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); + 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_bluez_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE); +} + +static void network_init(Network *self) +{ + self->priv = NETWORK_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void network_post_init(Network *self) +{ + g_assert(self->priv->dbus_g_proxy != NULL); + + /* 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); +} + +static void _network_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + Network *self = NETWORK(object); + + GHashTable *properties = network_get_properties(self, NULL); + if (properties == NULL) { + return; + } + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy))); + break; + + case PROP_CONNECTED: + g_value_set_boolean(value, g_value_get_boolean(g_hash_table_lookup(properties, "Connected"))); + break; + + case PROP_INTERFACE: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "Interface"))); + break; + + case PROP_UUID: + g_value_set_string(value, g_value_dup_string(g_hash_table_lookup(properties, "UUID"))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + g_hash_table_unref(properties); +} + +static void _network_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + Network *self = NETWORK(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + { + const gchar *dbus_object_path = g_value_get_string(value); + g_assert(dbus_object_path != NULL); + g_assert(self->priv->dbus_g_proxy == NULL); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_NETWORK_INTERFACE); + network_post_init(self); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* Methods */ + +/* string Connect(string uuid) */ +gchar *network_connect(Network *self, const gchar *uuid, GError **error) +{ + g_assert(self != NULL); + + gchar *ret; + + if (!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)) { + return NULL; + } + + return ret; +} + +/* void Disconnect() */ +void network_disconnect(Network *self, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* dict GetProperties() */ +GHashTable *network_get_properties(Network *self, GError **error) +{ + g_assert(self != NULL); + + GHashTable *ret; + + if (!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 NULL; + } + + return ret; +} + +/* Signals handlers */ +static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name, const GValue *value, gpointer data) +{ + Network *self = NETWORK(data); + g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value); +} + diff --git a/src/lib/network.h b/src/lib/network.h new file mode 100644 index 0000000..1010df6 --- /dev/null +++ b/src/lib/network.h @@ -0,0 +1,62 @@ +/* + * + * 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 __NETWORK_H +#define __NETWORK_H + +#include <glib-object.h> + +/* + * Type macros + */ +#define NETWORK_TYPE (network_get_type()) +#define NETWORK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NETWORK_TYPE, Network)) +#define NETWORK_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NETWORK_TYPE)) +#define NETWORK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NETWORK_TYPE, NetworkClass)) +#define NETWORK_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NETWORK_TYPE)) +#define NETWORK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NETWORK_TYPE, NetworkClass)) + +typedef struct _Network Network; +typedef struct _NetworkClass NetworkClass; +typedef struct _NetworkPrivate NetworkPrivate; + +struct _Network { + GObject parent_instance; + + /*< private >*/ + NetworkPrivate *priv; +}; + +struct _NetworkClass { + GObjectClass parent_class; +}; + +/* + * Method definitions + */ +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); + +#endif /* __NETWORK_H */ + diff --git a/src/lib/serial.c b/src/lib/serial.c new file mode 100644 index 0000000..2a375c7 --- /dev/null +++ b/src/lib/serial.c @@ -0,0 +1,138 @@ +/* + * + * 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 "dbus-common.h" +#include "marshallers.h" +#include "serial.h" + +#define BLUEZ_DBUS_SERIAL_INTERFACE "org.bluez.Serial" + +#define SERIAL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), SERIAL_TYPE, SerialPrivate)) + +struct _SerialPrivate { + DBusGProxy *dbus_g_proxy; +}; + +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_class_init(SerialClass *klass) +{ + g_type_class_add_private(klass, sizeof(SerialPrivate)); + + /* Properties registration */ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + 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); + + g_assert(conn != NULL); +} + +static void serial_post_init(Serial *self) +{ + g_assert(self->priv->dbus_g_proxy != NULL); +} + +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, g_strdup(dbus_g_proxy_get_path(self->priv->dbus_g_proxy))); + 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); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + { + const gchar *dbus_object_path = g_value_get_string(value); + g_assert(dbus_object_path != NULL); + g_assert(self->priv->dbus_g_proxy == NULL); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_SERIAL_INTERFACE); + serial_post_init(self); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +/* Methods */ + +/* string Connect(string pattern) */ +gchar *serial_connect(Serial *self, const gchar *pattern, GError **error) +{ + g_assert(self != NULL); + + gchar *ret; + + if (!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 NULL; + } + + return ret; +} + +/* void Disconnect(string device) */ +void serial_disconnect(Serial *self, const gchar *device, GError **error) +{ + g_assert(self != NULL); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_STRING, device, G_TYPE_INVALID, G_TYPE_INVALID); +} + diff --git a/src/lib/serial.h b/src/lib/serial.h new file mode 100644 index 0000000..1b7d556 --- /dev/null +++ b/src/lib/serial.h @@ -0,0 +1,61 @@ +/* + * + * 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> + +/* + * 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; +}; + +/* + * Method definitions + */ +gchar *serial_connect(Serial *self, const gchar *pattern, GError **error); +void serial_disconnect(Serial *self, const gchar *device, GError **error); + +#endif /* __SERIAL_H */ + |