diff options
author | Alexander Orlenko <zxteam@gmail.com> | 2010-07-28 14:57:51 +1100 |
---|---|---|
committer | Alexander Orlenko <zxteam@gmail.com> | 2010-07-28 14:57:51 +1100 |
commit | d8d2f60f3c58d8ce77927bd6d44d1c29cf06d1ae (patch) | |
tree | 62e96cd22e01ffaa8868d1df62289e7b4614cbc1 | |
parent | 9cef574490407c149831be8c7c89e50f77eb813c (diff) | |
download | bluez-tools-d8d2f60f3c58d8ce77927bd6d44d1c29cf06d1ae.tar.gz |
Fixed bluez api files (removed on fly patches)
Added OBEX api && support
A lot of small changes...
42 files changed, 3323 insertions, 186 deletions
diff --git a/contrib/bluez-api-4.66-fixed/adapter-api.txt b/contrib/bluez-api-4.66-fixed/adapter-api.txt index c960d43..0653ccd 100644 --- a/contrib/bluez-api-4.66-fixed/adapter-api.txt +++ b/contrib/bluez-api-4.66-fixed/adapter-api.txt @@ -102,8 +102,7 @@ Methods dict GetProperties() Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.Failed - object CreatePairedDevice(string address, object agent, - string capability) [async] + object CreatePairedDevice(string address, object agent, string capability) [async] Creates a new object path for a remote device. This method will connect to the remote device and retrieve diff --git a/contrib/bluez-api-4.66-fixed/control-api.txt b/contrib/bluez-api-4.66-fixed/control-api.txt index 1a42846..ce9d2bd 100644 --- a/contrib/bluez-api-4.66-fixed/control-api.txt +++ b/contrib/bluez-api-4.66-fixed/control-api.txt @@ -33,8 +33,7 @@ Methods void Connect() Adjust remote volume one step down - boolean SendPassthrough(avc_operation_id key, boolean state, - string op_data) + boolean SendPassthrough(avc_operation_id key, boolean state, string op_data) Called to send Passthrough commands. ONLY valid if BlueZ device is in CT role. @@ -93,8 +92,7 @@ Signals Connected() Sent when the AVRCP connection to the remote device has been disconnected. - Passthrough(uint8 key, boolean state, int32 company_id, - string op_data) + Passthrough(uint8 key, boolean state, int32 company_id, string op_data) Called when Passthrough command is received from connected device. diff --git a/contrib/agent.xml b/contrib/bluezAgent.xml index 86e442b..86e442b 100644 --- a/contrib/agent.xml +++ b/contrib/bluezAgent.xml diff --git a/contrib/gen-dbus-gobject.pl b/contrib/gen-dbus-gobject.pl index c9298eb..0f893be 100755 --- a/contrib/gen-dbus-gobject.pl +++ b/contrib/gen-dbus-gobject.pl @@ -40,30 +40,10 @@ sub parse_doc_api { $n++; s/\s+$//; - die "invalid file format (1)\n" if $n == 1 && $_ !~ /^BlueZ D-Bus \S+ API description$/; + die "invalid file format (1)\n" if $n == 1 && $_ !~ /^BlueZ D-Bus \S+ API description$/ && $_ !~ /^obex.*?API description$/i; /^\s*$/ && next; - # On-fly patches: - - # audio-api.txt - #s/void (PropertyChanged\(string name, variant value\))$/$1/; - #s/(string State)$/$1 [readonly]/; - #s/void (AnswerRequested\(\))/$1/; - #s/^p(roperties\tstring State \[readonly\])$/P$1/; - #s/ ( \[(readonly|readwrite)\])$/$1/; - #s/void (Ring\(string number\))$/$1/; - #s/void (CallTerminated\(\))$/$1/; - #s/void (CallStarted\(\))$/$1/; - #s/void (CallEnded\(\))$/$1/; - #s/^p(roperties\tboolean Connected \[readonly\])$/P$1/; - - # adapter-api.txt - #s/PaireableTimeout/PairableTimeout/; - - # device-api.txt - #s /dict (DiscoverServices\(string pattern\))$/dict{u,s} $1/; - if (/^(.+) hierarchy$/) { my $hierarchy = $1; $section = 'hierarchy'; @@ -74,12 +54,12 @@ sub parse_doc_api { } elsif (/^Service\s*(.+)$/) { my $service = $1; die "invalid file format (2)\n" unless $section eq 'hierarchy'; - die "invalid service: $service\n" unless $service eq 'org.bluez'; + die "invalid service: $service\n" unless $service eq 'org.bluez' || $service eq 'org.openobex' || $service eq 'org.openobex.client'; $data{'service'} = $service; } elsif (/^Interface\s*(.+)$/) { my $intf = $1; die "invalid file format (3)\n" unless $section eq 'hierarchy'; - die "invalid interface: $intf\n" unless $intf =~ /^org\.bluez/; + die "invalid interface: $intf\n" unless $intf =~ /^org\.(bluez|openobex)/; $data{'intf'} = $intf; $data{$intf} = undef; @@ -90,6 +70,10 @@ sub parse_doc_api { my $obj_path = $1; die "invalid file format (4)\n" unless $section eq 'hierarchy'; $data{'objectPath'} = $obj_path if $obj_path =~ /^[A-Za-z0-9\/]+$/; + } elsif (/^Object name\s*(.+)/) { + my $obj_name = $1; + die "invalid file format (4)\n" unless $section eq 'hierarchy'; + $data{'objectName'} = $obj_name if $obj_name =~ /^[A-Za-z]+$/; } elsif (/^Methods/) { die "invalid file format (5)\n" unless $section eq 'hierarchy'; $section = 'methods'; @@ -104,45 +88,22 @@ sub parse_doc_api { s/Properties/ /; } - if (defined $section && $section eq 'methods' && (/^\s+((\S+) (\w+)\((.*)\)( \[(\w+)\])?)$/ || /^\s+((\S+) (\w+)\((.*,))$/)) { + if (defined $section && $section eq 'methods' && /^\s+((\S+) (\w+)\((.*)\)( \[(\w+)\])?)$/) { my $decl = $1; my $ret = $2; my $name = $3; my $args = $4; my $flag = $6; - if ($decl =~ /,$/) { - my $add_str = <INPUT>; - # adapter-api.txt patch - #$add_str =~ s/(string capability\))$/$1 [async]/; - if ($add_str =~ /\s+(.+)\)( \[(\w+)\])?$/) { - $decl .= " $1)"; - $args .= " $1"; - $flag = $3; - } else { - die "invalid file format (8)\n"; - } - } - $data{$data{'intf'}}{'methods'}{$name}{'decl'} = $decl; $data{$data{'intf'}}{'methods'}{$name}{'ret'} = $ret; $data{$data{'intf'}}{'methods'}{$name}{'flag'} = $flag; @{$data{$data{'intf'}}{'methods'}{$name}{'args'}} = map {type => (split / /, $_)[0], name => (split / /, $_)[1]}, (split /, /, $args); - } elsif (defined $section && $section eq 'signals' && (/^\s+((\w+)\((.*)\))$/ || /^\s+((\w+)\((.*,))$/)) { + } elsif (defined $section && $section eq 'signals' && /^\s+((\w+)\((.*)\))$/) { my $decl = $1; my $name = $2; my $args = $3; - if ($decl =~ /,$/) { - my $add_str = <INPUT>; - if ($add_str =~ /\s+(.+)\)$/) { - $decl .= " $1)"; - $args .= " $1"; - } else { - die "invalid file format (9)\n"; - } - } - $data{$data{'intf'}}{'signals'}{$name}{'decl'} = $decl; @{$data{$data{'intf'}}{'signals'}{$name}{'args'}} = map {type => (split / /, $_)[0], name => (split / /, $_)[1]}, (split /, /, $args); } elsif (defined $section && $section eq 'properties' && /^\s+((\S+) (\w+) \[(readonly|readwrite)\])$/) { @@ -163,8 +124,6 @@ sub parse_doc_api { return \%data; } -my $data = parse_doc_api($ARGV[1], $ARGV[2]); - my $HEADER = <<EOH; /* * @@ -202,8 +161,10 @@ sub get_g_type { $g_type = 'gboolean ' if $bluez_type eq 'boolean'; $g_type = 'gint32 ' if $bluez_type eq 'int32'; $g_type = 'guint32 ' if $bluez_type eq 'uint32'; - $g_type = 'GPtrArray *' if $bluez_type eq 'array{object}'; + $g_type = 'guint64 ' if $bluez_type eq 'uint64'; + $g_type = 'GPtrArray *' if $bluez_type eq 'array{object}' || $bluez_type eq 'array{dict}'; $g_type = 'gchar **' if $bluez_type eq 'array{string}'; + $g_type = 'guchar ' if $bluez_type eq 'byte'; die "unknown bluez type (1): $bluez_type\n" unless defined $g_type; @@ -218,10 +179,15 @@ sub get_g_type_name { $g_type_name = 'G_TYPE_STRING' if $bluez_type eq 'string'; $g_type_name = 'G_TYPE_VALUE' if $bluez_type eq 'variant'; $g_type_name = 'G_TYPE_BOOLEAN' if $bluez_type eq 'boolean'; + $g_type_name = 'G_TYPE_INT' if $bluez_type eq 'int32'; $g_type_name = 'G_TYPE_UINT' if $bluez_type eq 'uint32'; + $g_type_name = 'G_TYPE_UINT64' if $bluez_type eq 'uint64'; $g_type_name = 'DBUS_TYPE_G_STRING_VARIANT_HASHTABLE' if $bluez_type eq 'dict'; $g_type_name = 'DBUS_TYPE_G_UINT_STRING_HASHTABLE' if $bluez_type eq 'dict{u,s}'; $g_type_name = 'DBUS_TYPE_G_OBJECT_ARRAY' if $bluez_type eq 'array{object}'; + $g_type_name = 'G_TYPE_STRV' if $bluez_type eq 'array{string}'; + $g_type_name = 'G_TYPE_UCHAR' if $bluez_type eq 'byte'; + $g_type_name = 'DBUS_TYPE_G_HASH_TABLE_ARRAY' if $bluez_type eq 'array{dict}'; die "unknown bluez type (2): $bluez_type\n" unless defined $g_type_name; @@ -289,7 +255,7 @@ GType {\$object}_get_type(void) G_GNUC_CONST; EOT my $intf = $node->{'intf'}; - my $obj = (split /\./, $intf)[-1]; + my $obj = exists $node->{'objectName'} ? $node->{'objectName'} : (split /\./, $intf)[-1]; my $obj_lc = lc join('_', $obj =~ /([A-Z]+[a-z]*)/g); my $obj_uc = uc join('_', $obj =~ /([A-Z]+[a-z]*)/g); @@ -346,6 +312,7 @@ sub generate_source { #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -361,10 +328,10 @@ struct _{\$Object}Private { DBusGProxy *introspection_g_proxy; gchar *introspection_xml; - {IF_PROPERTIES} + {IF_PROPERTIES_EXT} /* Properties */ {PRIV_PROPERTIES} - {FI_PROPERTIES} + {FI_PROPERTIES_EXT} {IF_ASYNC_CALLS} /* Async calls */ @@ -374,12 +341,17 @@ struct _{\$Object}Private { G_DEFINE_TYPE({\$Object}, {\$object}, G_TYPE_OBJECT); +{IF_PROPERTIES} enum { PROP_0, {ENUM_PROPERTIES} }; +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); +{FI_PROPERTIES} + {IF_SIGNALS} enum { {ENUM_SIGNALS}, @@ -388,12 +360,7 @@ 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); -{IF_SIGNALS} {SIGNALS_HANDLERS_DEF} {FI_SIGNALS} @@ -406,10 +373,10 @@ static void {\$object}_dispose(GObject *gobject) {SIGNALS_DISCONNECTION} {FI_SIGNALS} - {IF_PROPERTIES} + {IF_PROPERTIES_EXT} /* Properties free */ {PROPERTIES_FREE} - {FI_PROPERTIES} + {FI_PROPERTIES_EXT} /* Proxy free */ g_object_unref(self->priv->dbus_g_proxy); @@ -430,6 +397,7 @@ static void {\$object}_class_init({\$Object}Class *klass) g_type_class_add_private(klass, sizeof({\$Object}Private)); + {IF_PROPERTIES} /* Properties registration */ GParamSpec *pspec; @@ -437,6 +405,7 @@ static void {\$object}_class_init({\$Object}Class *klass) gobject_class->set_property = _{\$object}_set_property; {PROPERTIES_REGISTRATION} + {FI_PROPERTIES} {IF_SIGNALS} /* Signals registation */ @@ -457,7 +426,7 @@ static void {\$object}_init({\$Object} *self) {IF_INIT} GError *error = NULL; - + /* Getting introspection XML */ self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_{\$OBJECT}_PATH, "org.freedesktop.DBus.Introspectable"); self->priv->introspection_xml = NULL; @@ -481,10 +450,10 @@ static void {\$object}_init({\$Object} *self) {SIGNALS_CONNECTION} {FI_SIGNALS} - {IF_PROPERTIES} + {IF_PROPERTIES_EXT} /* Properties init */ {PROPERTIES_INIT} - {FI_PROPERTIES} + {FI_PROPERTIES_EXT} {FI_INIT} } @@ -519,13 +488,14 @@ static void {\$object}_post_init({\$Object} *self, const gchar *dbus_object_path {SIGNALS_CONNECTION} {FI_SIGNALS} - {IF_PROPERTIES} + {IF_PROPERTIES_EXT} /* Properties init */ {PROPERTIES_INIT} - {FI_PROPERTIES} + {FI_PROPERTIES_EXT} } {FI_POST_INIT} +{IF_PROPERTIES} static void _{\$object}_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { {\$Object} *self = {\$OBJECT}(object); @@ -557,6 +527,7 @@ static void _{\$object}_set_property(GObject *object, guint property_id, const G } g_assert(error == NULL); } +{FI_PROPERTIES} {IF_ASYNC_CALLS} static void {\$object}_async_notify_callback(DBusGProxy *proxy, DBusGProxyCall *call, gpointer data) @@ -572,8 +543,10 @@ static void {\$object}_async_notify_callback(DBusGProxy *proxy, DBusGProxyCall * {METHODS} +{IF_PROPERTIES} /* Properties access methods */ {PROPERTIES_ACCESS_METHODS} +{FI_PROPERTIES} {IF_SIGNALS} /* Signals handlers */ @@ -582,7 +555,7 @@ static void {\$object}_async_notify_callback(DBusGProxy *proxy, DBusGProxyCall * EOT my $intf = $node->{'intf'}; - my $obj = (split /\./, $intf)[-1]; + my $obj = exists $node->{'objectName'} ? $node->{'objectName'} : (split /\./, $intf)[-1]; my $obj_lc = lc join('_', $obj =~ /([A-Z]+[a-z]*)/g); my $obj_uc = uc join('_', $obj =~ /([A-Z]+[a-z]*)/g); @@ -689,6 +662,14 @@ EOT $signals_registration .= "\t\t\tg_cclosure_bluez_marshal_VOID__STRING_BOXED,\n". "\t\t\tG_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_HASH_TABLE);\n\n"; + } elsif ($arg_t eq 'object_boolean') { + $signals_registration .= + "\t\t\tg_cclosure_bluez_marshal_VOID__STRING_BOOLEAN,\n". + "\t\t\tG_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN);\n\n"; + } elsif ($arg_t eq 'int32_int32') { + $signals_registration .= + "\t\t\tg_cclosure_bluez_marshal_VOID__INT_INT,\n". + "\t\t\tG_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);\n\n"; } else { die "unknown signal arguments: $arg_t\n"; } @@ -835,7 +816,7 @@ EOT "\t\tg_strfreev(self->priv->$property_var);\n". "\t\tself->priv->$property_var = (gchar **) g_value_dup_boxed(value);\n"; } elsif ($p{'type'} eq 'uint32') { - $properties_registration .= "\tpspec = g_param_spec_uint(\"$property\", NULL, NULL, 0, 65535, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n"; + $properties_registration .= "\tpspec = g_param_spec_uint(\"$property\", NULL, NULL, 0, 0xFFFFFFFF, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n"; $properties_init .= "\tif (g_hash_table_lookup(properties, \"$property\")) {\n". "\t\tself->priv->$property_var = g_value_get_uint(g_hash_table_lookup(properties, \"$property\"));\n". @@ -844,6 +825,16 @@ EOT "\t}\n"; $get_properties .= "\t\tg_value_set_uint(value, $property_get_method(self));\n"; $properties_changed_handler .= "\t\tself->priv->$property_var = g_value_get_uint(value);\n"; + } elsif ($p{'type'} eq 'uint64') { + $properties_registration .= "\tpspec = g_param_spec_uint64(\"$property\", NULL, NULL, 0, 0xFFFFFFFFFFFFFFFF, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n"; + $properties_init .= + "\tif (g_hash_table_lookup(properties, \"$property\")) {\n". + "\t\tself->priv->$property_var = g_value_get_uint64(g_hash_table_lookup(properties, \"$property\"));\n". + "\t} else {\n". + "\t\tself->priv->$property_var = 0;\n". + "\t}\n"; + $get_properties .= "\t\tg_value_set_uint64(value, $property_get_method(self));\n"; + $properties_changed_handler .= "\t\tself->priv->$property_var = g_value_get_uint64(value);\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"; $properties_init .= @@ -854,6 +845,16 @@ EOT "\t}\n"; $get_properties .= "\t\tg_value_set_boolean(value, $property_get_method(self));\n"; $properties_changed_handler .= "\t\tself->priv->$property_var = g_value_get_boolean(value);\n"; + } elsif ($p{'type'} eq 'byte') { + $properties_registration .= "\tpspec = g_param_spec_uchar(\"$property\", NULL, NULL, 0, 0xFF, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n"; + $properties_init .= + "\tif (g_hash_table_lookup(properties, \"$property\")) {\n". + "\t\tself->priv->$property_var = g_value_get_uchar(g_hash_table_lookup(properties, \"$property\"));\n". + "\t} else {\n". + "\t\tself->priv->$property_var = 0;\n". + "\t}\n"; + $get_properties .= "\t\tg_value_set_uchar(value, $property_get_method(self));\n"; + $properties_changed_handler .= "\t\tself->priv->$property_var = g_value_get_uchar(value);\n"; } else { die "unknown property type: $p{'type'}\n"; } @@ -922,11 +923,16 @@ EOT } else { $output =~ s/\s+\{IF_SIGNALS\}.+?\{FI_SIGNALS\}//gs; } - if (scalar keys %{$node->{$intf}{'properties'}} > 0) { + if (scalar keys %{$node->{$intf}{'properties'}} > 0 || !defined $node->{'objectPath'}) { $output =~ s/\{IF_PROPERTIES\}\s+(.+?)\s+\{FI_PROPERTIES\}/$1/gs; } else { $output =~ s/\s+\{IF_PROPERTIES\}.+?\{FI_PROPERTIES\}//gs; } + if (scalar keys %{$node->{$intf}{'properties'}} > 0) { + $output =~ s/\{IF_PROPERTIES_EXT\}\s+(.+?)\s+\{FI_PROPERTIES_EXT\}/$1/gs; + } else { + $output =~ s/\s+\{IF_PROPERTIES_EXT\}.+?\{FI_PROPERTIES_EXT\}//gs; + } if ($async_flag == 1) { $output =~ s/\{IF_ASYNC_CALLS\}\s+(.+?)\s+\{FI_ASYNC_CALLS\}/$1/gs; } else { @@ -962,5 +968,7 @@ EOT return $output; } +my $data = parse_doc_api($ARGV[1], $ARGV[2]); + print generate_header($data) if $ARGV[0] eq '-header'; print generate_source($data) if $ARGV[0] eq '-source'; diff --git a/contrib/generate-all.sh b/contrib/generate-all.sh index 2e4c4ba..274a176 100755 --- a/contrib/generate-all.sh +++ b/contrib/generate-all.sh @@ -1,5 +1,7 @@ #!/bin/sh +# BlueZ API + # adapter-api.txt ./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/adapter-api.txt > ../src/lib/adapter.h ./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/adapter-api.txt > ../src/lib/adapter.c @@ -24,15 +26,12 @@ ./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/network-api.txt > ../src/lib/network.h ./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/network-api.txt > ../src/lib/network.c -# network-api.txt ./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/network-api.txt 2 > ../src/lib/network_hub.h ./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/network-api.txt 2 > ../src/lib/network_hub.c -# network-api.txt ./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/network-api.txt 3 > ../src/lib/network_peer.h ./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/network-api.txt 3 > ../src/lib/network_peer.c -# network-api.txt ./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/network-api.txt 4 > ../src/lib/network_router.h ./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/network-api.txt 4 > ../src/lib/network_router.c @@ -43,3 +42,28 @@ # service-api.txt #./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/service-api.txt > ../src/lib/service.h #./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/service-api.txt > ../src/lib/service.c + +# OBEX API + +# client-api.txt +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/client-api.txt > ../src/lib/obexclient.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/client-api.txt > ../src/lib/obexclient.c + +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/client-api.txt 2 > ../src/lib/obexclient_session.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/client-api.txt 2 > ../src/lib/obexclient_session.c + +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/client-api.txt 3 > ../src/lib/obexclient_file_transfer.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/client-api.txt 3 > ../src/lib/obexclient_file_transfer.c + +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/client-api.txt 6 > ../src/lib/obexclient_transfer.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/client-api.txt 6 > ../src/lib/obexclient_transfer.c + +# obexd-api.txt +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/obexd-api.txt > ../src/lib/obexmanager.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/obexd-api.txt > ../src/lib/obexmanager.c + +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/obexd-api.txt 2 > ../src/lib/obextransfer.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/obexd-api.txt 2 > ../src/lib/obextransfer.c + +./gen-dbus-gobject.pl -header obexd-api-0.29-fixed/obexd-api.txt 3 > ../src/lib/obexsession.h +./gen-dbus-gobject.pl -source obexd-api-0.29-fixed/obexd-api.txt 3 > ../src/lib/obexsession.c diff --git a/contrib/obexAgent.xml b/contrib/obexAgent.xml new file mode 100644 index 0000000..d405c22 --- /dev/null +++ b/contrib/obexAgent.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<node name="/ObexAgent"> + <interface name="org.openobex.Agent"> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="obexagent"/> + + <method name="Authorize"> + <arg type="o" name="transfer" direction="in"/> + <arg type="s" name="bt_address" direction="in"/> + <arg type="s" name="name" direction="in"/> + <arg type="s" name="type" direction="in"/> + <arg type="i" name="length" direction="in"/> + <arg type="i" name="time" direction="in"/> + <arg type="s" direction="out"/> + </method> + <method name="Cancel"/> + + <method name="Release"/> + <method name="Request"> + <arg type="o" name="transfer" direction="in"/> + <arg type="s" direction="out"/> + </method> + <method name="Progress"> + <arg type="o" name="transfer" direction="in"/> + <arg type="t" name="transferred" direction="in"/> + </method> + <method name="Complete"> + <arg type="o" name="transfer" direction="in"/> + </method> + <method name="Error"> + <arg type="o" name="transfer" direction="in"/> + <arg type="s" name="message" direction="in"/> + </method> + + </interface> +</node> diff --git a/contrib/obexd-api-0.29-fixed/agent-api.txt b/contrib/obexd-api-0.29-fixed/agent-api.txt new file mode 100644 index 0000000..74f339c --- /dev/null +++ b/contrib/obexd-api-0.29-fixed/agent-api.txt @@ -0,0 +1,31 @@ +obexd Agent API description +********************************** + +Copyright (C) 2007-2010 Nokia Corporation +Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org> + + +Agent hierarchy +=============== + +Service unique name +Interface org.openobex.Agent +Object path freely definable + +Methods + string Authorize(object transfer, string bt_address, string name, + string type, int32 length, int32 time) + + This method gets called when the service daemon + needs to accept/reject a Bluetooth object push request. + Returns the full path (including the filename) where + the object shall be stored. + + Possible errors: org.openobex.Error.Rejected + org.openobex.Error.Canceled + + void Cancel() + + This method gets called to indicate that the agent + request failed before a reply was returned. It cancels + the previous request. diff --git a/contrib/obexd-api-0.29-fixed/client-api.txt b/contrib/obexd-api-0.29-fixed/client-api.txt new file mode 100644 index 0000000..3bfd134 --- /dev/null +++ b/contrib/obexd-api-0.29-fixed/client-api.txt @@ -0,0 +1,328 @@ +OBEX client API description +*************************** + +Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org> + + +Client hierarchy +================ + +Service org.openobex.client +Interface org.openobex.Client +Object path / +Object name OBEXClient + +Methods void SendFiles(dict device, array{string} files, object agent) + + Send one or multiple local files to the specified + device. The device is configured via properties. At + least the Destination property should be specified. + + void PullBusinessCard(dict device, string file) + + Request the business card from a remote device and + store it in the local file. + + void ExchangeBusinessCards(dict device, string clientfile, string file) + + Push the client's business card to the remote device + and then retrieve the remote business card and store + it in a local file. + + object CreateSession(dict device) + + Create a new OBEX session. The device is configured + via properties like in SendFiles. + + void RemoveSession(object session) + + Unregister session and abort pending transfers. + + string GetCapabilities(dict device) + + Get remote device capabilities. + +Properties string Target + + string Source + + string Destination + + byte Channel + + +Session hierarchy +================= + +Service org.openobex.client +Interface org.openobex.Session +Object path [variable prefix]/{session0,session1,...} +Object name OBEXClientSession + +Methods dict GetProperties() + + Returns all properties for the session. + + void AssignAgent(object agent) + + Assign an OBEX agent to this session. This allows + detailed progress reports about the transactions. + + void ReleaseAgent(object agent) + + Release a previously assigned OBEX agent. + +Properties string Source [readonly] + + string Destination [readonly] + + byte Channel [readonly] + + +File Transfer hierarchy +======================= + +Service org.openobex.client +Interface org.openobex.FileTransfer +Object path [variable prefix]/{session0,session1,...} +Object name OBEXClientFileTransfer + +Methods void ChangeFolder(string folder) + + Change the current folder of the remote device. + + void CreateFolder(string folder) + + Create a new folder in the remote device. + + array{dict} ListFolder() + + Returns a dictionary containing information about + the current folder content. + + The following keys are defined: + + string Name : Object name in UTF-8 format + string Type : Either "folder" or "file" + uint64 Size : Object size or number of items in folder + string Permission : Group, owner and other permission + guint64 Modified : Last change + guint64 Accessed : Last access + guint64 Created : Creation date + + void GetFile(string targetfile, string sourcefile) + + Copy the source file (from remote device) to the + target file (on local filesystem). + + A new Transfer object is created to represent this + transaction. + + void PutFile(string sourcefile, string targetfile) + + Copy the source file (from local filesystem) to the + target file (on remote device). + + A new Transfer object is created to represent this + transaction. + + void CopyFile(string sourcefile, string targetfile) + + Copy a file within the remote device from source file + to target file. + + void MoveFile(string sourcefile, string targetfile) + + Movea file within the remote device from source file + to the target file. + + void Delete(string file) + + Deletes the specified file/folder. + + +Phonebook Access hierarchy +======================= + +Service org.openobex.client +Interface org.openobex.PhonebookAccess +Object path [variable prefix]/{session0,session1,...} + +Methods void Select(string location, string phonebook) + + Select the phonebook object for other operations. Should + be call before all the other operations. + + location : Where the phonebook is stored, possible inputs : + "INT" ( "INTERNAL" which is default ) + "SIM" ( "SIM1" ) + "SIM2" + ... + + phonebook : Possible inputs : + "pb" : phonebook for the saved contacts + "ich": incoming call history + "och": outgoing call history + "mch": missing call history + "cch": combination of ich och mch + + string PullAll() + + Return the entire phonebook object from the PSE server + in plain string with vcard format. + + array{string vcard, string name} List() {FIX!} + + Return an array of vcard-listing data which contains the + vcard : name paired string, for example "1.vcf" : "John". + + string Pull(string vcard) + + Retrieve the vcard in the current phonebook object + for example : Pull("0.vcf") + + array{string vcard, string name} Search(string field, string value) {FIX!} + + Return an array of vcard-listing data which contains the + vcard : name paired string match the search condition. + + field : the field in the vcard to search with + { "name" (default) | "number" | "sound" } + value : the string value to search for + + uint16 GetSize() + + Return the number of the non-null entries in the selected + phonebook object. + + void SetFormat(string format) + + Indicate the format of the vcard that should be return by + related methods. + + format : { "vcard21" (default) | "vcard30" } + + void SetOrder(string order) + + Indicate the sorting method of the vcard-listing data returned + by List and Search methods. + + order : { "indexed" (default) | "alphanumeric" | "phonetic" } + + void SetFilter(array{string}) {FIX!??} + + Indicate fields that should be contained in vcards return by + related methods. + + Give an empty array will clear the filter and return all fields + available in vcards. And this is the default behavior. + + Possible filter fields : "VERSION", "FN", ..., "ALL", "bit[0-63]" + + array{string} ListFilterFields() {FIX!??} + + Return All Available fields that can be used in SefFilter method. + + array{string} GetFilter() + + Return the current filter setting + +Synchronization hierarchy +======================= + +Service org.openobex.client +Interface org.openobex.Synchronization +Object path [variable prefix]/{session0,session1,...} + +Methods void SetLocation(string location) + + Set the phonebook object store location for other operations. Should + be called before all the other operations. + + location: Where the phonebook is stored, possible values: + "INT" ( "INTERNAL" which is default ) + "SIM1" + "SIM2" + ...... + + string GetPhonebook() + + retrieve an entire Phonebook Object store from remote device + + void PutPhonebook(string obj) + + send an entire Phonebook Object store to remote device + +Transfer hierarchy +================== + +Service org.openobex.client +Interface org.openobex.Transfer +Object path [variable prefix]/{transfer0,transfer1,...} +Object name OBEXClientTransfer + +Methods dict GetProperties() + + Returns all properties for the transfer. See the + properties section for available properties. + + void Cancel() + + Cancels this transfer. + +Properties string Name [readonly] + + Name of the transferred object. + + uint64 Size [readonly] + + Size of the transferred object. If the size is + unknown, then this property will not be present. + + string Filename [readonly] + + Complete name of the file being received or sent. + + +Agent hierarchy +=============== + +Service unique name +Interface org.openobex.Agent +Object path freely definable + +Methods void Release() + + This method gets called when the service daemon + unregisters the agent. An agent can use it to do + cleanup tasks. There is no need to unregister the + agent, because when this method gets called it has + already been unregistered. + + string Request(object transfer) + + Accept or reject a new transfer (client and server) + and provide the filename for it. + + In case of incoming transfers it is the filename + where to store the file and for outgoing transfers + it is the filename to show the remote device. If left + empty it will be calculated automatically. + + Possible errors: org.openobex.Error.Rejected + org.openobex.Error.Canceled + + void Progress(object transfer, uint64 transferred) + + Progress within the transfer has been made. The + number of transferred bytes is given as second + argument for convenience. + + void Complete(object transfer) + + Informs that the transfer has completed sucessfully. + + void Error(object transfer, string message) + + Informs that the transfer has been terminated because + of some error. diff --git a/contrib/obexd-api-0.29-fixed/obexd-api.txt b/contrib/obexd-api-0.29-fixed/obexd-api.txt new file mode 100644 index 0000000..6cfaac7 --- /dev/null +++ b/contrib/obexd-api-0.29-fixed/obexd-api.txt @@ -0,0 +1,90 @@ +obexd API description +********************************** + +Copyright (C) 2007-2010 Nokia Corporation +Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org> + + +Manager hierarchy +=============== + +Service org.openobex +Interface org.openobex.Manager +Object path / +Object name OBEXManager + +Methods + void RegisterAgent(object agent) + + Register an agent to request authorization of + the user to accept/reject objects. Object push + service needs to authorize each received object. + + Possible errors: org.openobex.Error.AlreadyExists + + void UnregisterAgent(object agent) + + This unregisters the agent that has been previously + registered. The object path parameter must match the + same value that has been used on registration. + + Possible errors: org.openobex.Error.DoesNotExist + +Signals SessionCreated(object session) + + Signal sent when OBEX connection has been accepted. + (FTP only) + + SessionRemoved(object session) + + Sent when the transport is disconnected + (FTP only) + + TransferStarted(object transfer) + + Signal sent when an object push operation starts. + (OPP only) + + TransferCompleted(object transfer, boolean success) + + Signal sent when the object has been received + or an error happens. + (OPP only) + + +Transfer hierarchy +=============== + +Service org.openobex +Interface org.openobex.Transfer +Object path /transfer{0, 1, 2, ...} +Object name OBEXTransfer + +Methods + void Cancel() + + Stops the current transference. + +Signals + Progress(int32 total, int32 transfered) + + +Session hierarchy +=============== + +Service org.openobex +Interface org.openobex.Session +Object path /session{0, 1, 2, ...} +Object name OBEXSession + +Methods + dict GetProperties() + + +Signals TBD + + +Properties + string Address [readonly] + + Bluetooth device address or USB diff --git a/src/Makefile.am b/src/Makefile.am index aab0406..9881950 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,15 @@ lib_sources = lib/marshallers.c lib/marshallers.h \ lib/network_peer.c lib/network_peer.h \ lib/network_router.c lib/network_router.h \ lib/serial.c lib/serial.h \ - lib/sdp.c lib/sdp.h + lib/sdp.c lib/sdp.h \ + lib/obexagent.c lib/obexagent.h \ + lib/obexclient.c lib\obexclient.h \ + lib/obexclient_file_transfer.c lib/obexclient_file_transfer.h \ + lib/obexclient_session.c lib/obexclient_session.h \ + lib/obexclient_transfer.c lib/obexclient_transfer.h \ + lib/obexmanager.c lib/obexmanager.h \ + lib/obexsession.c lib/obexsession.h \ + lib/obextransfer.c lib/obextransfer.h bin_PROGRAMS = bt-monitor bt-adapter bt-agent bt-device bt-input bt-audio bt-network bt-serial bt_monitor_SOURCES = $(lib_sources) bt-monitor.c diff --git a/src/lib/adapter.c b/src/lib/adapter.c index 009c037..0c14db8 100644 --- a/src/lib/adapter.c +++ b/src/lib/adapter.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -76,6 +77,9 @@ enum { PROP_UUIDS /* readonly */ }; +static void _adapter_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _adapter_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + enum { DEVICE_CREATED, DEVICE_DISAPPEARED, @@ -88,9 +92,6 @@ enum { static guint signals[LAST_SIGNAL] = {0}; -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 device_created_handler(DBusGProxy *dbus_g_proxy, const gchar *device, gpointer data); static void device_disappeared_handler(DBusGProxy *dbus_g_proxy, const gchar *address, gpointer data); static void device_found_handler(DBusGProxy *dbus_g_proxy, const gchar *address, GHashTable *values, gpointer data); @@ -148,7 +149,7 @@ static void adapter_class_init(AdapterClass *klass) g_object_class_install_property(gobject_class, PROP_ADDRESS, pspec); /* uint32 Class [readonly] */ - pspec = g_param_spec_uint("Class", NULL, NULL, 0, 65535, 0, G_PARAM_READABLE); + pspec = g_param_spec_uint("Class", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READABLE); g_object_class_install_property(gobject_class, PROP_CLASS, pspec); /* array{object} Devices [readonly] */ @@ -160,7 +161,7 @@ static void adapter_class_init(AdapterClass *klass) g_object_class_install_property(gobject_class, PROP_DISCOVERABLE, pspec); /* uint32 DiscoverableTimeout [readwrite] */ - pspec = g_param_spec_uint("DiscoverableTimeout", NULL, NULL, 0, 65535, 0, G_PARAM_READWRITE); + pspec = g_param_spec_uint("DiscoverableTimeout", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READWRITE); g_object_class_install_property(gobject_class, PROP_DISCOVERABLE_TIMEOUT, pspec); /* boolean Discovering [readonly] */ @@ -176,7 +177,7 @@ static void adapter_class_init(AdapterClass *klass) g_object_class_install_property(gobject_class, PROP_PAIRABLE, pspec); /* uint32 PairableTimeout [readwrite] */ - pspec = g_param_spec_uint("PairableTimeout", NULL, NULL, 0, 65535, 0, G_PARAM_READWRITE); + pspec = g_param_spec_uint("PairableTimeout", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READWRITE); g_object_class_install_property(gobject_class, PROP_PAIRABLE_TIMEOUT, pspec); /* boolean Powered [readwrite] */ @@ -502,7 +503,7 @@ gchar *adapter_create_device(Adapter *self, const gchar *address, GError **error return ret; } -/* object CreatePairedDevice(string address, object agent, string capability) */ +/* object CreatePairedDevice(string address, object agent, string capability) [async] */ void adapter_create_paired_device_begin(Adapter *self, void (*AsyncNotifyFunc)(gpointer data), gpointer data, const gchar *address, const gchar *agent, const gchar *capability) { g_assert(ADAPTER_IS(self)); diff --git a/src/lib/agent.h b/src/lib/agent.h index 2c80d2c..7fbad37 100644 --- a/src/lib/agent.h +++ b/src/lib/agent.h @@ -34,10 +34,10 @@ /* * Type macros */ -#define AGENT_TYPE (agent_get_type()) -#define AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGENT_TYPE, Agent)) +#define AGENT_TYPE (agent_get_type()) +#define AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGENT_TYPE, Agent)) #define AGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), AGENT_TYPE)) -#define AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), AGENT_TYPE, AgentClass)) +#define AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), AGENT_TYPE, AgentClass)) #define AGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), AGENT_TYPE)) #define AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), AGENT_TYPE, AgentClass)) diff --git a/src/lib/audio.c b/src/lib/audio.c index 3e02761..d9574aa 100644 --- a/src/lib/audio.c +++ b/src/lib/audio.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -53,6 +54,9 @@ enum { PROP_STATE /* readonly */ }; +static void _audio_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _audio_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + enum { PROPERTY_CHANGED, @@ -61,9 +65,6 @@ enum { 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_dispose(GObject *gobject) diff --git a/src/lib/dbus-common.c b/src/lib/dbus-common.c index 0045d5a..aaf6bca 100644 --- a/src/lib/dbus-common.c +++ b/src/lib/dbus-common.c @@ -27,6 +27,7 @@ #include "marshallers.h" #include "agent.h" +#include "obexagent.h" #include "dbus-common.h" DBusGConnection *conn = NULL; @@ -38,11 +39,16 @@ gboolean dbus_connect(GError **error) return FALSE; } - /* Marshallers registration */ + /* Marshallers registration + * Used for signals + */ dbus_g_object_register_marshaller(g_cclosure_bluez_marshal_VOID__STRING_BOXED, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); + dbus_g_object_register_marshaller(g_cclosure_bluez_marshal_VOID__STRING_BOOLEAN, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_object_register_marshaller(g_cclosure_bluez_marshal_VOID__INT_INT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); - /* Agent installation */ + /* Agents installation */ dbus_g_object_type_install_info(AGENT_TYPE, &dbus_glib_agent_object_info); + dbus_g_object_type_install_info(OBEXAGENT_TYPE, &dbus_glib_obexagent_object_info); return TRUE; } diff --git a/src/lib/dbus-common.h b/src/lib/dbus-common.h index 6c84620..2358ffd 100644 --- a/src/lib/dbus-common.h +++ b/src/lib/dbus-common.h @@ -31,6 +31,7 @@ #define DBUS_TYPE_G_STRING_VARIANT_HASHTABLE (dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) #define DBUS_TYPE_G_UINT_STRING_HASHTABLE (dbus_g_type_get_map("GHashTable", G_TYPE_UINT, G_TYPE_STRING)) +#define DBUS_TYPE_G_HASH_TABLE_ARRAY (dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_STRING_VARIANT_HASHTABLE)) extern DBusGConnection *conn; diff --git a/src/lib/device.c b/src/lib/device.c index 04ba636..cad503f 100644 --- a/src/lib/device.c +++ b/src/lib/device.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -77,6 +78,9 @@ enum { PROP_UUIDS /* readonly */ }; +static void _device_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _device_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + enum { DISCONNECT_REQUESTED, NODE_CREATED, @@ -88,9 +92,6 @@ enum { 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); @@ -161,7 +162,7 @@ static void device_class_init(DeviceClass *klass) 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); + pspec = g_param_spec_uint("Class", NULL, NULL, 0, 0xFFFFFFFF, 0, G_PARAM_READABLE); g_object_class_install_property(gobject_class, PROP_CLASS, pspec); /* boolean Connected [readonly] */ diff --git a/src/lib/input.c b/src/lib/input.c index a5e7f17..34b1397 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -53,6 +54,9 @@ enum { PROP_CONNECTED /* readonly */ }; +static void _input_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _input_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + enum { PROPERTY_CHANGED, @@ -61,9 +65,6 @@ enum { 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_dispose(GObject *gobject) diff --git a/src/lib/manager.c b/src/lib/manager.c index 978fd58..6d80422 100644 --- a/src/lib/manager.c +++ b/src/lib/manager.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -52,6 +53,9 @@ enum { PROP_ADAPTERS /* readonly */ }; +static void _manager_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _manager_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + enum { ADAPTER_ADDED, ADAPTER_REMOVED, @@ -63,9 +67,6 @@ enum { static guint signals[LAST_SIGNAL] = {0}; -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 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); @@ -150,7 +151,7 @@ static void manager_init(Manager *self) g_assert(conn != NULL); GError *error = NULL; - + /* Getting introspection XML */ self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_MANAGER_PATH, "org.freedesktop.DBus.Introspectable"); self->priv->introspection_xml = NULL; diff --git a/src/lib/marshallers.c b/src/lib/marshallers.c index 80801c6..f72799e 100644 --- a/src/lib/marshallers.c +++ b/src/lib/marshallers.c @@ -84,7 +84,161 @@ g_cclosure_bluez_marshal_VOID__STRING_BOXED (GClosure *closure, data2); } -/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:2) */ +/* VOID:STRING,BOOLEAN (lib/marshallers.list:2) */ +void +g_cclosure_bluez_marshal_VOID__STRING_BOOLEAN (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer data1, + gpointer arg_1, + gboolean arg_2, + gpointer data2); + register GMarshalFunc_VOID__STRING_BOOLEAN callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boolean (param_values + 2), + data2); +} + +/* VOID:INT,INT (lib/marshallers.list:3) */ +void +g_cclosure_bluez_marshal_VOID__INT_INT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gpointer data2); + register GMarshalFunc_VOID__INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + data2); +} + +/* BOOLEAN:POINTER (lib/marshallers.list:4) */ +void +g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1, + gpointer arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:STRING,POINTER (lib/marshallers.list:5) */ +void +g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__STRING_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:6) */ void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure, GValue *return_value G_GNUC_UNUSED, @@ -129,7 +283,7 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closur g_value_set_boolean (return_value, v_return); } -/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:3) */ +/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:7) */ void g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure, GValue *return_value G_GNUC_UNUSED, @@ -172,46 +326,7 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure, g_value_set_boolean (return_value, v_return); } -/* BOOLEAN:POINTER (lib/marshallers.list:4) */ -void -g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1, - gpointer arg_1, - gpointer data2); - register GMarshalFunc_BOOLEAN__POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 2); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - data2); - - g_value_set_boolean (return_value, v_return); -} - -/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:5) */ +/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:8) */ void g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure, GValue *return_value G_GNUC_UNUSED, @@ -254,7 +369,7 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure, g_value_set_boolean (return_value, v_return); } -/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:6) */ +/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:9) */ void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure, GValue *return_value G_GNUC_UNUSED, @@ -297,20 +412,116 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure, g_value_set_boolean (return_value, v_return); } -/* BOOLEAN:STRING,POINTER (lib/marshallers.list:7) */ +/* BOOLEAN:BOXED,STRING,STRING,STRING,INT,INT,POINTER,POINTER (lib/marshallers.list:10) */ void -g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) +g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) { - typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_BOOLEAN__STRING_POINTER callback; + typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer arg_4, + gint arg_5, + gint arg_6, + gpointer arg_7, + gpointer arg_8, + gpointer data2); + register GMarshalFunc_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 9); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_boxed (param_values + 1), + g_marshal_value_peek_string (param_values + 2), + g_marshal_value_peek_string (param_values + 3), + g_marshal_value_peek_string (param_values + 4), + g_marshal_value_peek_int (param_values + 5), + g_marshal_value_peek_int (param_values + 6), + g_marshal_value_peek_pointer (param_values + 7), + g_marshal_value_peek_pointer (param_values + 8), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:BOXED,UINT64,POINTER (lib/marshallers.list:11) */ +void +g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT64_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_UINT64_POINTER) (gpointer data1, + gpointer arg_1, + guint64 arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_BOOLEAN__BOXED_UINT64_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__BOXED_UINT64_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_boxed (param_values + 1), + g_marshal_value_peek_uint64 (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:BOXED,POINTER (lib/marshallers.list:12) */ +void +g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__BOXED_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; @@ -328,10 +539,10 @@ g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } - callback = (GMarshalFunc_BOOLEAN__STRING_POINTER) (marshal_data ? marshal_data : cc->callback); + callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, - g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); diff --git a/src/lib/marshallers.h b/src/lib/marshallers.h index 121b114..dfc47ca 100644 --- a/src/lib/marshallers.h +++ b/src/lib/marshallers.h @@ -14,7 +14,39 @@ extern void g_cclosure_bluez_marshal_VOID__STRING_BOXED (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:2) */ +/* VOID:STRING,BOOLEAN (lib/marshallers.list:2) */ +extern void g_cclosure_bluez_marshal_VOID__STRING_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:INT,INT (lib/marshallers.list:3) */ +extern void g_cclosure_bluez_marshal_VOID__INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:POINTER (lib/marshallers.list:4) */ +extern void g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:STRING,POINTER (lib/marshallers.list:5) */ +extern void g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:6) */ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, @@ -22,7 +54,7 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure gpointer invocation_hint, gpointer marshal_data); -/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:3) */ +/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:7) */ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, @@ -30,15 +62,7 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure gpointer invocation_hint, gpointer marshal_data); -/* BOOLEAN:POINTER (lib/marshallers.list:4) */ -extern void g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:5) */ +/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:8) */ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, @@ -46,7 +70,7 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure gpointer invocation_hint, gpointer marshal_data); -/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:6) */ +/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:9) */ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, @@ -54,13 +78,29 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure * gpointer invocation_hint, gpointer marshal_data); -/* BOOLEAN:STRING,POINTER (lib/marshallers.list:7) */ -extern void g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); +/* BOOLEAN:BOXED,STRING,STRING,STRING,INT,INT,POINTER,POINTER (lib/marshallers.list:10) */ +extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:BOXED,UINT64,POINTER (lib/marshallers.list:11) */ +extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT64_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:BOXED,POINTER (lib/marshallers.list:12) */ +extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); G_END_DECLS diff --git a/src/lib/marshallers.list b/src/lib/marshallers.list index 4096a34..d666ad4 100644 --- a/src/lib/marshallers.list +++ b/src/lib/marshallers.list @@ -1,7 +1,12 @@ VOID:STRING,BOXED +VOID:STRING,BOOLEAN +VOID:INT,INT +BOOLEAN:POINTER +BOOLEAN:STRING,POINTER BOOLEAN:BOXED,UINT,UCHAR,POINTER BOOLEAN:BOXED,STRING,POINTER -BOOLEAN:POINTER BOOLEAN:BOXED,POINTER,POINTER BOOLEAN:BOXED,UINT,POINTER -BOOLEAN:STRING,POINTER +BOOLEAN:BOXED,STRING,STRING,STRING,INT,INT,POINTER,POINTER +BOOLEAN:BOXED,UINT64,POINTER +BOOLEAN:BOXED,POINTER diff --git a/src/lib/network.c b/src/lib/network.c index 092c05e..1aad2c9 100644 --- a/src/lib/network.c +++ b/src/lib/network.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" @@ -57,6 +58,9 @@ enum { PROP_UUID /* readonly */ }; +static void _network_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _network_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + enum { PROPERTY_CHANGED, @@ -65,9 +69,6 @@ enum { 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_dispose(GObject *gobject) diff --git a/src/lib/network_hub.c b/src/lib/network_hub.c index a746488..1079390 100644 --- a/src/lib/network_hub.c +++ b/src/lib/network_hub.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" diff --git a/src/lib/network_peer.c b/src/lib/network_peer.c index 032619d..81c8200 100644 --- a/src/lib/network_peer.c +++ b/src/lib/network_peer.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" diff --git a/src/lib/network_router.c b/src/lib/network_router.c index 6f8c576..ac24b2c 100644 --- a/src/lib/network_router.c +++ b/src/lib/network_router.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" diff --git a/src/lib/obexagent.c b/src/lib/obexagent.c new file mode 100644 index 0000000..dd8af91 --- /dev/null +++ b/src/lib/obexagent.c @@ -0,0 +1,174 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <glib.h> + +#include "dbus-common.h" +#include "obexclient_transfer.h" +#include "obexagent.h" + +#define OBEXAGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXAGENT_TYPE, OBEXAgentPrivate)) + +struct _OBEXAgentPrivate { + DBusGProxy *proxy; +}; + +G_DEFINE_TYPE(OBEXAgent, obexagent, G_TYPE_OBJECT); + +static void obexagent_dispose(GObject *gobject) +{ + OBEXAgent *self = OBEXAGENT(gobject); + + dbus_g_connection_unregister_g_object(conn, gobject); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexagent_parent_class)->dispose(gobject); +} + +static void obexagent_class_init(OBEXAgentClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexagent_dispose; + + g_type_class_add_private(klass, sizeof(OBEXAgentPrivate)); +} + +static void obexagent_init(OBEXAgent *self) +{ + self->priv = OBEXAGENT_GET_PRIVATE(self); + + g_assert(conn != NULL); + + dbus_g_connection_register_g_object(conn, DBUS_OBEXAGENT_PATH, G_OBJECT(self)); + + g_print("OBEX Agent registered\n"); +} + +/* Methods */ + +/* Agent API */ +gboolean obexagent_authorize(OBEXAgent *self, const gchar *transfer, const gchar *bt_address, const gchar *name, const gchar *type, gint length, gint time, gchar **ret, GError **error) +{ + *ret = NULL; + g_print("[Bluetooth ObjectPush request]\n"); + OBEXClientTransfer *transfer_obj = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); + g_print(" Transfer: %s (%llu bytes), %s\n", obexclient_transfer_get_name(transfer_obj), obexclient_transfer_get_size(transfer_obj), obexclient_transfer_get_filename(transfer_obj)); + g_object_unref(transfer_obj); + g_print(" Address: %s\n", bt_address); + g_print(" Name: %s\n", name); + g_print(" Type: %s\n", type); + g_print(" Length: %d\n", length); + g_print(" Time: %d\n", time); + + gchar yn[4] = {0,}; + g_print("Accept (yes/no)? "); + errno = 0; + if (scanf("%3s", yn) == EOF && errno) { + g_warning("%s\n", strerror(errno)); + } + if (g_strcmp0(yn, "y") == 0 || g_strcmp0(yn, "yes") == 0) { + *ret = g_strdup("/home/zak/obp.ext"); + return TRUE; + } else { + // TODO: Fix error code + if (error) + *error = g_error_new(g_quark_from_static_string("org.openobex.Error.Rejected"), 0, "File transfer rejected"); + return FALSE; + } + + return TRUE; +} + +gboolean obexagent_cancel(OBEXAgent *self, GError **error) +{ + g_print("Request cancelled\n"); + return TRUE; +} + +/* Client API */ +gboolean obexagent_release(OBEXAgent *self, GError **error) +{ + g_print("OBEX Agent released\n"); + return TRUE; +} + +gboolean obexagent_request(OBEXAgent *self, const gchar *transfer, gchar **ret, GError **error) +{ + *ret = NULL; + OBEXClientTransfer *transfer_obj = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); + g_print("Transfer: %s (%llu bytes), %s\n", obexclient_transfer_get_name(transfer_obj), obexclient_transfer_get_size(transfer_obj), obexclient_transfer_get_filename(transfer_obj)); + g_object_unref(transfer_obj); + + gchar yn[4] = {0,}; + g_print("Accept (yes/no)? "); + errno = 0; + if (scanf("%3s", yn) == EOF && errno) { + g_warning("%s\n", strerror(errno)); + } + if (g_strcmp0(yn, "y") == 0 || g_strcmp0(yn, "yes") == 0) { + return TRUE; + } else { + // TODO: Fix error code + if (error) + *error = g_error_new(g_quark_from_static_string("org.openobex.Error.Rejected"), 0, "File transfer rejected"); + return FALSE; + } + + return TRUE; +} + +gboolean obexagent_progress(OBEXAgent *self, const gchar *transfer, guint64 transferred, GError **error) +{ + OBEXClientTransfer *transfer_obj = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); + g_print("Transfer progress: %s (%llu/%llu bytes), %s\n", obexclient_transfer_get_name(transfer_obj), transferred, obexclient_transfer_get_size(transfer_obj), obexclient_transfer_get_filename(transfer_obj)); + g_object_unref(transfer_obj); + + return TRUE; +} + +gboolean obexagent_complete(OBEXAgent *self, const gchar *transfer, GError **error) +{ + OBEXClientTransfer *transfer_obj = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); + g_print("Transfer complete: %s (%llu bytes), %s\n", obexclient_transfer_get_name(transfer_obj), obexclient_transfer_get_size(transfer_obj), obexclient_transfer_get_filename(transfer_obj)); + g_object_unref(transfer_obj); + + return TRUE; +} + +gboolean obexagent_error(OBEXAgent *self, const gchar *transfer, const gchar *message, GError **error) +{ + OBEXClientTransfer *transfer_obj = g_object_new(OBEXCLIENT_TRANSFER_TYPE, "DBusObjectPath", transfer, NULL); + g_print("Transfer error: %s (%llu bytes), %s: %s\n", obexclient_transfer_get_name(transfer_obj), obexclient_transfer_get_size(transfer_obj), obexclient_transfer_get_filename(transfer_obj), message); + g_object_unref(transfer_obj); + + return TRUE; +} + diff --git a/src/lib/obexagent.h b/src/lib/obexagent.h new file mode 100644 index 0000000..fefbc43 --- /dev/null +++ b/src/lib/obexagent.h @@ -0,0 +1,98 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEXAGENT_H +#define __OBEXAGENT_H + +#include <glib-object.h> +#include <dbus/dbus-glib.h> + +#include "marshallers.h" + +#define DBUS_OBEXAGENT_PATH "/ObexAgent" + +/* + * Type macros + */ +#define OBEXAGENT_TYPE (obexagent_get_type()) +#define OBEXAGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXAGENT_TYPE, OBEXAgent)) +#define OBEXAGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXAGENT_TYPE)) +#define OBEXAGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXAGENT_TYPE, OBEXAgentClass)) +#define OBEXAGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXAGENT_TYPE)) +#define OBEXAGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXAGENT_TYPE, OBEXAgentClass)) + +typedef struct _OBEXAgent OBEXAgent; +typedef struct _OBEXAgentClass OBEXAgentClass; +typedef struct _OBEXAgentPrivate OBEXAgentPrivate; + +struct _OBEXAgent { + GObject parent_instance; + + /*< private >*/ + OBEXAgentPrivate *priv; +}; + +struct _OBEXAgentClass { + GObjectClass parent_class; +}; + +/* used by OBEXAGENT_TYPE */ +GType obexagent_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ + +/* Agent API */ +gboolean obexagent_authorize(OBEXAgent *self, const gchar *transfer, const gchar *bt_address, const gchar *name, const gchar *type, gint length, gint time, gchar **ret, GError **error); +gboolean obexagent_cancel(OBEXAgent *self, GError **error); + +/* Client API */ +gboolean obexagent_release(OBEXAgent *self, GError **error); +gboolean obexagent_request(OBEXAgent *self, const gchar *transfer, gchar **ret, GError **error); +gboolean obexagent_progress(OBEXAgent *self, const gchar *transfer, guint64 transferred, GError **error); +gboolean obexagent_complete(OBEXAgent *self, const gchar *transfer, GError **error); +gboolean obexagent_error(OBEXAgent *self, const gchar *transfer, const gchar *message, GError **error); + +/* Glue code */ +static const DBusGMethodInfo dbus_glib_obexagent_methods[] = { + { (GCallback) obexagent_authorize, g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_STRING_STRING_INT_INT_POINTER_POINTER, 0}, + { (GCallback) obexagent_cancel, g_cclosure_bluez_marshal_BOOLEAN__POINTER, 111}, + { (GCallback) obexagent_release, g_cclosure_bluez_marshal_BOOLEAN__POINTER, 140}, + { (GCallback) obexagent_request, g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER, 170}, + { (GCallback) obexagent_progress, g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT64_POINTER, 226}, + { (GCallback) obexagent_complete, g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER, 286}, + { (GCallback) obexagent_error, g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER, 330}, +}; + +static const DBusGObjectInfo dbus_glib_obexagent_object_info = { + 0, + dbus_glib_obexagent_methods, + 7, + "org.openobex.Agent\0Authorize\0S\0transfer\0I\0o\0bt_address\0I\0s\0name\0I\0s\0type\0I\0s\0length\0I\0i\0time\0I\0i\0arg6\0O\0F\0N\0s\0\0org.openobex.Agent\0Cancel\0S\0\0org.openobex.Agent\0Release\0S\0\0org.openobex.Agent\0Request\0S\0transfer\0I\0o\0arg1\0O\0F\0N\0s\0\0org.openobex.Agent\0Progress\0S\0transfer\0I\0o\0transferred\0I\0t\0\0org.openobex.Agent\0Complete\0S\0transfer\0I\0o\0\0org.openobex.Agent\0Error\0S\0transfer\0I\0o\0message\0I\0s\0\0\0", + "\0", + "\0" +}; + +#endif /* __OBEXAGENT_H */ + diff --git a/src/lib/obexclient.c b/src/lib/obexclient.c new file mode 100644 index 0000000..45a8e5e --- /dev/null +++ b/src/lib/obexclient.c @@ -0,0 +1,152 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obexclient.h" + +#define OBEXCLIENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_TYPE, OBEXClientPrivate)) + +struct _OBEXClientPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; +}; + +G_DEFINE_TYPE(OBEXClient, obexclient, G_TYPE_OBJECT); + +static void obexclient_dispose(GObject *gobject) +{ + OBEXClient *self = OBEXCLIENT(gobject); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexclient_parent_class)->dispose(gobject); +} + +static void obexclient_class_init(OBEXClientClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexclient_dispose; + + g_type_class_add_private(klass, sizeof(OBEXClientPrivate)); +} + +static void obexclient_init(OBEXClient *self) +{ + self->priv = OBEXCLIENT_GET_PRIVATE(self); + + g_assert(conn != NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_OBEXCLIENT_PATH, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXCLIENT_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXCLIENT_INTERFACE, BLUEZ_DBUS_OBEXCLIENT_PATH); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_OBEXCLIENT_PATH, BLUEZ_DBUS_OBEXCLIENT_INTERFACE); +} + +/* Methods */ + +/* object CreateSession(dict device) */ +gchar *obexclient_create_session(OBEXClient *self, const GHashTable *device, GError **error) +{ + g_assert(OBEXCLIENT_IS(self)); + + gchar *ret = NULL; + dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateSession", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID); + + return ret; +} + +/* void ExchangeBusinessCards(dict device, string clientfile, string file) */ +void obexclient_exchange_business_cards(OBEXClient *self, const GHashTable *device, const gchar *clientfile, const gchar *file, GError **error) +{ + g_assert(OBEXCLIENT_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "ExchangeBusinessCards", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_STRING, clientfile, G_TYPE_STRING, file, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* string GetCapabilities(dict device) */ +gchar *obexclient_get_capabilities(OBEXClient *self, const GHashTable *device, GError **error) +{ + g_assert(OBEXCLIENT_IS(self)); + + gchar *ret = NULL; + dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetCapabilities", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID); + + return ret; +} + +/* void PullBusinessCard(dict device, string file) */ +void obexclient_pull_business_card(OBEXClient *self, const GHashTable *device, const gchar *file, GError **error) +{ + g_assert(OBEXCLIENT_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "PullBusinessCard", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_STRING, file, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void RemoveSession(object session) */ +void obexclient_remove_session(OBEXClient *self, const gchar *session, GError **error) +{ + g_assert(OBEXCLIENT_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoveSession", error, DBUS_TYPE_G_OBJECT_PATH, session, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void SendFiles(dict device, array{string} files, object agent) */ +void obexclient_send_files(OBEXClient *self, const GHashTable *device, const gchar **files, const gchar *agent, GError **error) +{ + g_assert(OBEXCLIENT_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "SendFiles", error, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, device, G_TYPE_STRV, files, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); +} + diff --git a/src/lib/obexclient.h b/src/lib/obexclient.h new file mode 100644 index 0000000..b527dc7 --- /dev/null +++ b/src/lib/obexclient.h @@ -0,0 +1,71 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEXCLIENT_H +#define __OBEXCLIENT_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXCLIENT_PATH "/" +#define BLUEZ_DBUS_OBEXCLIENT_INTERFACE "org.openobex.Client" + +/* + * Type macros + */ +#define OBEXCLIENT_TYPE (obexclient_get_type()) +#define OBEXCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_TYPE, OBEXClient)) +#define OBEXCLIENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_TYPE)) +#define OBEXCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_TYPE, OBEXClientClass)) +#define OBEXCLIENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_TYPE)) +#define OBEXCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_TYPE, OBEXClientClass)) + +typedef struct _OBEXClient OBEXClient; +typedef struct _OBEXClientClass OBEXClientClass; +typedef struct _OBEXClientPrivate OBEXClientPrivate; + +struct _OBEXClient { + GObject parent_instance; + + /*< private >*/ + OBEXClientPrivate *priv; +}; + +struct _OBEXClientClass { + GObjectClass parent_class; +}; + +/* used by OBEXCLIENT_TYPE */ +GType obexclient_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +gchar *obexclient_create_session(OBEXClient *self, const GHashTable *device, GError **error); +void obexclient_exchange_business_cards(OBEXClient *self, const GHashTable *device, const gchar *clientfile, const gchar *file, GError **error); +gchar *obexclient_get_capabilities(OBEXClient *self, const GHashTable *device, GError **error); +void obexclient_pull_business_card(OBEXClient *self, const GHashTable *device, const gchar *file, GError **error); +void obexclient_remove_session(OBEXClient *self, const gchar *session, GError **error); +void obexclient_send_files(OBEXClient *self, const GHashTable *device, const gchar **files, const gchar *agent, GError **error); + +#endif /* __OBEXCLIENT_H */ + diff --git a/src/lib/obexclient_file_transfer.c b/src/lib/obexclient_file_transfer.c new file mode 100644 index 0000000..883c37c --- /dev/null +++ b/src/lib/obexclient_file_transfer.c @@ -0,0 +1,234 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obexclient_file_transfer.h" + +#define OBEXCLIENT_FILE_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransferPrivate)) + +struct _OBEXClientFileTransferPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; +}; + +G_DEFINE_TYPE(OBEXClientFileTransfer, obexclient_file_transfer, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obexclient_file_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obexclient_file_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void obexclient_file_transfer_dispose(GObject *gobject) +{ + OBEXClientFileTransfer *self = OBEXCLIENT_FILE_TRANSFER(gobject); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexclient_file_transfer_parent_class)->dispose(gobject); +} + +static void obexclient_file_transfer_class_init(OBEXClientFileTransferClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexclient_file_transfer_dispose; + + g_type_class_add_private(klass, sizeof(OBEXClientFileTransferPrivate)); + + /* Properties registration */ + GParamSpec *pspec; + + gobject_class->get_property = _obexclient_file_transfer_get_property; + gobject_class->set_property = _obexclient_file_transfer_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); +} + +static void obexclient_file_transfer_init(OBEXClientFileTransfer *self) +{ + self->priv = OBEXCLIENT_FILE_TRANSFER_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void obexclient_file_transfer_post_init(OBEXClientFileTransfer *self, const gchar *dbus_object_path) +{ + g_assert(dbus_object_path != NULL); + g_assert(strlen(dbus_object_path) > 0); + g_assert(self->priv->dbus_g_proxy == NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXCLIENT_FILE_TRANSFER_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXCLIENT_FILE_TRANSFER_INTERFACE, dbus_object_path); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXCLIENT_FILE_TRANSFER_INTERFACE); +} + +static void _obexclient_file_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + OBEXClientFileTransfer *self = OBEXCLIENT_FILE_TRANSFER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obexclient_file_transfer_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obexclient_file_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + OBEXClientFileTransfer *self = OBEXCLIENT_FILE_TRANSFER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + obexclient_file_transfer_post_init(self, g_value_get_string(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); +} + +/* Methods */ + +/* void ChangeFolder(string folder) */ +void obexclient_file_transfer_change_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "ChangeFolder", error, G_TYPE_STRING, folder, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void CopyFile(string sourcefile, string targetfile) */ +void obexclient_file_transfer_copy_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "CopyFile", error, G_TYPE_STRING, sourcefile, G_TYPE_STRING, targetfile, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void CreateFolder(string folder) */ +void obexclient_file_transfer_create_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateFolder", error, G_TYPE_STRING, folder, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void Delete(string file) */ +void obexclient_file_transfer_delete(OBEXClientFileTransfer *self, const gchar *file, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "Delete", error, G_TYPE_STRING, file, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void GetFile(string targetfile, string sourcefile) */ +void obexclient_file_transfer_get_file(OBEXClientFileTransfer *self, const gchar *targetfile, const gchar *sourcefile, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetFile", error, G_TYPE_STRING, targetfile, G_TYPE_STRING, sourcefile, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* array{dict} ListFolder() */ +GPtrArray *obexclient_file_transfer_list_folder(OBEXClientFileTransfer *self, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + GPtrArray *ret = NULL; + dbus_g_proxy_call(self->priv->dbus_g_proxy, "ListFolder", error, G_TYPE_INVALID, DBUS_TYPE_G_HASH_TABLE_ARRAY, &ret, G_TYPE_INVALID); + + return ret; +} + +/* void MoveFile(string sourcefile, string targetfile) */ +void obexclient_file_transfer_move_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "MoveFile", error, G_TYPE_STRING, sourcefile, G_TYPE_STRING, targetfile, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void PutFile(string sourcefile, string targetfile) */ +void obexclient_file_transfer_put_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "PutFile", error, G_TYPE_STRING, sourcefile, G_TYPE_STRING, targetfile, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* Properties access methods */ +const gchar *obexclient_file_transfer_get_dbus_object_path(OBEXClientFileTransfer *self) +{ + g_assert(OBEXCLIENT_FILE_TRANSFER_IS(self)); + + return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); +} + diff --git a/src/lib/obexclient_file_transfer.h b/src/lib/obexclient_file_transfer.h new file mode 100644 index 0000000..38ac15e --- /dev/null +++ b/src/lib/obexclient_file_transfer.h @@ -0,0 +1,74 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEXCLIENT_FILE_TRANSFER_H +#define __OBEXCLIENT_FILE_TRANSFER_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXCLIENT_FILE_TRANSFER_INTERFACE "org.openobex.FileTransfer" + +/* + * Type macros + */ +#define OBEXCLIENT_FILE_TRANSFER_TYPE (obexclient_file_transfer_get_type()) +#define OBEXCLIENT_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransfer)) +#define OBEXCLIENT_FILE_TRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_FILE_TRANSFER_TYPE)) +#define OBEXCLIENT_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransferClass)) +#define OBEXCLIENT_FILE_TRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_FILE_TRANSFER_TYPE)) +#define OBEXCLIENT_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_FILE_TRANSFER_TYPE, OBEXClientFileTransferClass)) + +typedef struct _OBEXClientFileTransfer OBEXClientFileTransfer; +typedef struct _OBEXClientFileTransferClass OBEXClientFileTransferClass; +typedef struct _OBEXClientFileTransferPrivate OBEXClientFileTransferPrivate; + +struct _OBEXClientFileTransfer { + GObject parent_instance; + + /*< private >*/ + OBEXClientFileTransferPrivate *priv; +}; + +struct _OBEXClientFileTransferClass { + GObjectClass parent_class; +}; + +/* used by OBEXCLIENT_FILE_TRANSFER_TYPE */ +GType obexclient_file_transfer_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +void obexclient_file_transfer_change_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error); +void obexclient_file_transfer_copy_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); +void obexclient_file_transfer_create_folder(OBEXClientFileTransfer *self, const gchar *folder, GError **error); +void obexclient_file_transfer_delete(OBEXClientFileTransfer *self, const gchar *file, GError **error); +void obexclient_file_transfer_get_file(OBEXClientFileTransfer *self, const gchar *targetfile, const gchar *sourcefile, GError **error); +GPtrArray *obexclient_file_transfer_list_folder(OBEXClientFileTransfer *self, GError **error); +void obexclient_file_transfer_move_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); +void obexclient_file_transfer_put_file(OBEXClientFileTransfer *self, const gchar *sourcefile, const gchar *targetfile, GError **error); + +const gchar *obexclient_file_transfer_get_dbus_object_path(OBEXClientFileTransfer *self); + +#endif /* __OBEXCLIENT_FILE_TRANSFER_H */ + diff --git a/src/lib/obexclient_session.c b/src/lib/obexclient_session.c new file mode 100644 index 0000000..929ad59 --- /dev/null +++ b/src/lib/obexclient_session.c @@ -0,0 +1,282 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obexclient_session.h" + +#define OBEXCLIENT_SESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_SESSION_TYPE, OBEXClientSessionPrivate)) + +struct _OBEXClientSessionPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; + + /* Properties */ + guchar channel; + gchar *destination; + gchar *source; +}; + +G_DEFINE_TYPE(OBEXClientSession, obexclient_session, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ + PROP_CHANNEL, /* readonly */ + PROP_DESTINATION, /* readonly */ + PROP_SOURCE /* readonly */ +}; + +static void _obexclient_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obexclient_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void obexclient_session_dispose(GObject *gobject) +{ + OBEXClientSession *self = OBEXCLIENT_SESSION(gobject); + + /* Properties free */ + g_free(self->priv->destination); + g_free(self->priv->source); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexclient_session_parent_class)->dispose(gobject); +} + +static void obexclient_session_class_init(OBEXClientSessionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexclient_session_dispose; + + g_type_class_add_private(klass, sizeof(OBEXClientSessionPrivate)); + + /* Properties registration */ + GParamSpec *pspec; + + gobject_class->get_property = _obexclient_session_get_property; + gobject_class->set_property = _obexclient_session_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + + /* byte Channel [readonly] */ + pspec = g_param_spec_uchar("Channel", NULL, NULL, 0, 0xFF, 0, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_CHANNEL, pspec); + + /* string Destination [readonly] */ + pspec = g_param_spec_string("Destination", NULL, NULL, NULL, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_DESTINATION, pspec); + + /* string Source [readonly] */ + pspec = g_param_spec_string("Source", NULL, NULL, NULL, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_SOURCE, pspec); +} + +static void obexclient_session_init(OBEXClientSession *self) +{ + self->priv = OBEXCLIENT_SESSION_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void obexclient_session_post_init(OBEXClientSession *self, const gchar *dbus_object_path) +{ + g_assert(dbus_object_path != NULL); + g_assert(strlen(dbus_object_path) > 0); + g_assert(self->priv->dbus_g_proxy == NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXCLIENT_SESSION_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXCLIENT_SESSION_INTERFACE, dbus_object_path); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXCLIENT_SESSION_INTERFACE); + + /* Properties init */ + GHashTable *properties = obexclient_session_get_properties(self, &error); + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + g_assert(properties != NULL); + + /* byte Channel [readonly] */ + if (g_hash_table_lookup(properties, "Channel")) { + self->priv->channel = g_value_get_uchar(g_hash_table_lookup(properties, "Channel")); + } else { + self->priv->channel = 0; + } + + /* string Destination [readonly] */ + if (g_hash_table_lookup(properties, "Destination")) { + self->priv->destination = g_value_dup_string(g_hash_table_lookup(properties, "Destination")); + } else { + self->priv->destination = g_strdup("undefined"); + } + + /* string Source [readonly] */ + if (g_hash_table_lookup(properties, "Source")) { + self->priv->source = g_value_dup_string(g_hash_table_lookup(properties, "Source")); + } else { + self->priv->source = g_strdup("undefined"); + } + + g_hash_table_unref(properties); +} + +static void _obexclient_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + OBEXClientSession *self = OBEXCLIENT_SESSION(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obexclient_session_get_dbus_object_path(self)); + break; + + case PROP_CHANNEL: + g_value_set_uchar(value, obexclient_session_get_channel(self)); + break; + + case PROP_DESTINATION: + g_value_set_string(value, obexclient_session_get_destination(self)); + break; + + case PROP_SOURCE: + g_value_set_string(value, obexclient_session_get_source(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obexclient_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + OBEXClientSession *self = OBEXCLIENT_SESSION(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + obexclient_session_post_init(self, g_value_get_string(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); +} + +/* Methods */ + +/* void AssignAgent(object agent) */ +void obexclient_session_assign_agent(OBEXClientSession *self, const gchar *agent, GError **error) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "AssignAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* dict GetProperties() */ +GHashTable *obexclient_session_get_properties(OBEXClientSession *self, GError **error) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + GHashTable *ret = NULL; + dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); + + return ret; +} + +/* void ReleaseAgent(object agent) */ +void obexclient_session_release_agent(OBEXClientSession *self, const gchar *agent, GError **error) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "ReleaseAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* Properties access methods */ +const gchar *obexclient_session_get_dbus_object_path(OBEXClientSession *self) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); +} + +const guchar obexclient_session_get_channel(OBEXClientSession *self) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + return self->priv->channel; +} + +const gchar *obexclient_session_get_destination(OBEXClientSession *self) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + return self->priv->destination; +} + +const gchar *obexclient_session_get_source(OBEXClientSession *self) +{ + g_assert(OBEXCLIENT_SESSION_IS(self)); + + return self->priv->source; +} + diff --git a/src/lib/obexclient_session.h b/src/lib/obexclient_session.h new file mode 100644 index 0000000..e3715e8 --- /dev/null +++ b/src/lib/obexclient_session.h @@ -0,0 +1,72 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEXCLIENT_SESSION_H +#define __OBEXCLIENT_SESSION_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXCLIENT_SESSION_INTERFACE "org.openobex.Session" + +/* + * Type macros + */ +#define OBEXCLIENT_SESSION_TYPE (obexclient_session_get_type()) +#define OBEXCLIENT_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_SESSION_TYPE, OBEXClientSession)) +#define OBEXCLIENT_SESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_SESSION_TYPE)) +#define OBEXCLIENT_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_SESSION_TYPE, OBEXClientSessionClass)) +#define OBEXCLIENT_SESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_SESSION_TYPE)) +#define OBEXCLIENT_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_SESSION_TYPE, OBEXClientSessionClass)) + +typedef struct _OBEXClientSession OBEXClientSession; +typedef struct _OBEXClientSessionClass OBEXClientSessionClass; +typedef struct _OBEXClientSessionPrivate OBEXClientSessionPrivate; + +struct _OBEXClientSession { + GObject parent_instance; + + /*< private >*/ + OBEXClientSessionPrivate *priv; +}; + +struct _OBEXClientSessionClass { + GObjectClass parent_class; +}; + +/* used by OBEXCLIENT_SESSION_TYPE */ +GType obexclient_session_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +void obexclient_session_assign_agent(OBEXClientSession *self, const gchar *agent, GError **error); +GHashTable *obexclient_session_get_properties(OBEXClientSession *self, GError **error); +void obexclient_session_release_agent(OBEXClientSession *self, const gchar *agent, GError **error); + +const gchar *obexclient_session_get_dbus_object_path(OBEXClientSession *self); +const guchar obexclient_session_get_channel(OBEXClientSession *self); +const gchar *obexclient_session_get_destination(OBEXClientSession *self); +const gchar *obexclient_session_get_source(OBEXClientSession *self); + +#endif /* __OBEXCLIENT_SESSION_H */ + diff --git a/src/lib/obexclient_transfer.c b/src/lib/obexclient_transfer.c new file mode 100644 index 0000000..a3a47e5 --- /dev/null +++ b/src/lib/obexclient_transfer.c @@ -0,0 +1,274 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obexclient_transfer.h" + +#define OBEXCLIENT_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransferPrivate)) + +struct _OBEXClientTransferPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; + + /* Properties */ + gchar *filename; + gchar *name; + guint64 size; +}; + +G_DEFINE_TYPE(OBEXClientTransfer, obexclient_transfer, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ + PROP_FILENAME, /* readonly */ + PROP_NAME, /* readonly */ + PROP_SIZE /* readonly */ +}; + +static void _obexclient_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obexclient_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void obexclient_transfer_dispose(GObject *gobject) +{ + OBEXClientTransfer *self = OBEXCLIENT_TRANSFER(gobject); + + /* Properties free */ + g_free(self->priv->filename); + g_free(self->priv->name); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexclient_transfer_parent_class)->dispose(gobject); +} + +static void obexclient_transfer_class_init(OBEXClientTransferClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexclient_transfer_dispose; + + g_type_class_add_private(klass, sizeof(OBEXClientTransferPrivate)); + + /* Properties registration */ + GParamSpec *pspec; + + gobject_class->get_property = _obexclient_transfer_get_property; + gobject_class->set_property = _obexclient_transfer_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + + /* string Filename [readonly] */ + pspec = g_param_spec_string("Filename", NULL, NULL, NULL, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_FILENAME, pspec); + + /* string Name [readonly] */ + pspec = g_param_spec_string("Name", NULL, NULL, NULL, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_NAME, pspec); + + /* uint64 Size [readonly] */ + pspec = g_param_spec_uint64("Size", NULL, NULL, 0, 0xFFFFFFFFFFFFFFFF, 0, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_SIZE, pspec); +} + +static void obexclient_transfer_init(OBEXClientTransfer *self) +{ + self->priv = OBEXCLIENT_TRANSFER_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void obexclient_transfer_post_init(OBEXClientTransfer *self, const gchar *dbus_object_path) +{ + g_assert(dbus_object_path != NULL); + g_assert(strlen(dbus_object_path) > 0); + g_assert(self->priv->dbus_g_proxy == NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXCLIENT_TRANSFER_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXCLIENT_TRANSFER_INTERFACE, dbus_object_path); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXCLIENT_TRANSFER_INTERFACE); + + /* Properties init */ + GHashTable *properties = obexclient_transfer_get_properties(self, &error); + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + g_assert(properties != NULL); + + /* string Filename [readonly] */ + if (g_hash_table_lookup(properties, "Filename")) { + self->priv->filename = g_value_dup_string(g_hash_table_lookup(properties, "Filename")); + } else { + self->priv->filename = g_strdup("undefined"); + } + + /* string Name [readonly] */ + if (g_hash_table_lookup(properties, "Name")) { + self->priv->name = g_value_dup_string(g_hash_table_lookup(properties, "Name")); + } else { + self->priv->name = g_strdup("undefined"); + } + + /* uint64 Size [readonly] */ + if (g_hash_table_lookup(properties, "Size")) { + self->priv->size = g_value_get_uint64(g_hash_table_lookup(properties, "Size")); + } else { + self->priv->size = 0; + } + + g_hash_table_unref(properties); +} + +static void _obexclient_transfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + OBEXClientTransfer *self = OBEXCLIENT_TRANSFER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obexclient_transfer_get_dbus_object_path(self)); + break; + + case PROP_FILENAME: + g_value_set_string(value, obexclient_transfer_get_filename(self)); + break; + + case PROP_NAME: + g_value_set_string(value, obexclient_transfer_get_name(self)); + break; + + case PROP_SIZE: + g_value_set_uint64(value, obexclient_transfer_get_size(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obexclient_transfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + OBEXClientTransfer *self = OBEXCLIENT_TRANSFER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + obexclient_transfer_post_init(self, g_value_get_string(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); +} + +/* Methods */ + +/* void Cancel() */ +void obexclient_transfer_cancel(OBEXClientTransfer *self, GError **error) +{ + g_assert(OBEXCLIENT_TRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "Cancel", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* dict GetProperties() */ +GHashTable *obexclient_transfer_get_properties(OBEXClientTransfer *self, GError **error) +{ + g_assert(OBEXCLIENT_TRANSFER_IS(self)); + + GHashTable *ret = NULL; + dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); + + return ret; +} + +/* Properties access methods */ +const gchar *obexclient_transfer_get_dbus_object_path(OBEXClientTransfer *self) +{ + g_assert(OBEXCLIENT_TRANSFER_IS(self)); + + return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); +} + +const gchar *obexclient_transfer_get_filename(OBEXClientTransfer *self) +{ + g_assert(OBEXCLIENT_TRANSFER_IS(self)); + + return self->priv->filename; +} + +const gchar *obexclient_transfer_get_name(OBEXClientTransfer *self) +{ + g_assert(OBEXCLIENT_TRANSFER_IS(self)); + + return self->priv->name; +} + +const guint64 obexclient_transfer_get_size(OBEXClientTransfer *self) +{ + g_assert(OBEXCLIENT_TRANSFER_IS(self)); + + return self->priv->size; +} + diff --git a/src/lib/obexclient_transfer.h b/src/lib/obexclient_transfer.h new file mode 100644 index 0000000..5bed1b5 --- /dev/null +++ b/src/lib/obexclient_transfer.h @@ -0,0 +1,71 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEXCLIENT_TRANSFER_H +#define __OBEXCLIENT_TRANSFER_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXCLIENT_TRANSFER_INTERFACE "org.openobex.Transfer" + +/* + * Type macros + */ +#define OBEXCLIENT_TRANSFER_TYPE (obexclient_transfer_get_type()) +#define OBEXCLIENT_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransfer)) +#define OBEXCLIENT_TRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXCLIENT_TRANSFER_TYPE)) +#define OBEXCLIENT_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransferClass)) +#define OBEXCLIENT_TRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXCLIENT_TRANSFER_TYPE)) +#define OBEXCLIENT_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXCLIENT_TRANSFER_TYPE, OBEXClientTransferClass)) + +typedef struct _OBEXClientTransfer OBEXClientTransfer; +typedef struct _OBEXClientTransferClass OBEXClientTransferClass; +typedef struct _OBEXClientTransferPrivate OBEXClientTransferPrivate; + +struct _OBEXClientTransfer { + GObject parent_instance; + + /*< private >*/ + OBEXClientTransferPrivate *priv; +}; + +struct _OBEXClientTransferClass { + GObjectClass parent_class; +}; + +/* used by OBEXCLIENT_TRANSFER_TYPE */ +GType obexclient_transfer_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +void obexclient_transfer_cancel(OBEXClientTransfer *self, GError **error); +GHashTable *obexclient_transfer_get_properties(OBEXClientTransfer *self, GError **error); + +const gchar *obexclient_transfer_get_dbus_object_path(OBEXClientTransfer *self); +const gchar *obexclient_transfer_get_filename(OBEXClientTransfer *self); +const gchar *obexclient_transfer_get_name(OBEXClientTransfer *self); +const guint64 obexclient_transfer_get_size(OBEXClientTransfer *self); + +#endif /* __OBEXCLIENT_TRANSFER_H */ + diff --git a/src/lib/obexmanager.c b/src/lib/obexmanager.c new file mode 100644 index 0000000..8096679 --- /dev/null +++ b/src/lib/obexmanager.c @@ -0,0 +1,212 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obexmanager.h" + +#define OBEXMANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXMANAGER_TYPE, OBEXManagerPrivate)) + +struct _OBEXManagerPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; +}; + +G_DEFINE_TYPE(OBEXManager, obexmanager, G_TYPE_OBJECT); + +enum { + SESSION_CREATED, + SESSION_REMOVED, + TRANSFER_COMPLETED, + TRANSFER_STARTED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +static void session_created_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data); +static void session_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data); +static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, const gboolean success, gpointer data); +static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, gpointer data); + +static void obexmanager_dispose(GObject *gobject) +{ + OBEXManager *self = OBEXMANAGER(gobject); + + /* DBus signals disconnection */ + dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionCreated", G_CALLBACK(session_created_handler), self); + dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionRemoved", G_CALLBACK(session_removed_handler), self); + dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self); + dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexmanager_parent_class)->dispose(gobject); +} + +static void obexmanager_class_init(OBEXManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexmanager_dispose; + + g_type_class_add_private(klass, sizeof(OBEXManagerPrivate)); + + /* Signals registation */ + signals[SESSION_CREATED] = g_signal_new("SessionCreated", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[SESSION_REMOVED] = g_signal_new("SessionRemoved", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[TRANSFER_COMPLETED] = g_signal_new("TransferCompleted", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_bluez_marshal_VOID__STRING_BOOLEAN, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN); + + signals[TRANSFER_STARTED] = g_signal_new("TransferStarted", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); +} + +static void obexmanager_init(OBEXManager *self) +{ + self->priv = OBEXMANAGER_GET_PRIVATE(self); + + g_assert(conn != NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_OBEXMANAGER_PATH, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXMANAGER_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXMANAGER_INTERFACE, BLUEZ_DBUS_OBEXMANAGER_PATH); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_OBEXMANAGER_PATH, BLUEZ_DBUS_OBEXMANAGER_INTERFACE); + + /* DBus signals connection */ + + /* SessionCreated(object session) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionCreated", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionCreated", G_CALLBACK(session_created_handler), self, NULL); + + /* SessionRemoved(object session) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionRemoved", G_CALLBACK(session_removed_handler), self, NULL); + + /* TransferCompleted(object transfer, boolean success) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferCompleted", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self, NULL); + + /* TransferStarted(object transfer) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferStarted", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self, NULL); +} + +/* Methods */ + +/* void RegisterAgent(object agent) */ +void obexmanager_register_agent(OBEXManager *self, const gchar *agent, GError **error) +{ + g_assert(OBEXMANAGER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "RegisterAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* void UnregisterAgent(object agent) */ +void obexmanager_unregister_agent(OBEXManager *self, const gchar *agent, GError **error) +{ + g_assert(OBEXMANAGER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "UnregisterAgent", error, DBUS_TYPE_G_OBJECT_PATH, agent, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* Signals handlers */ +static void session_created_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data) +{ + OBEXManager *self = OBEXMANAGER(data); + + g_signal_emit(self, signals[SESSION_CREATED], 0, session); +} + +static void session_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *session, gpointer data) +{ + OBEXManager *self = OBEXMANAGER(data); + + g_signal_emit(self, signals[SESSION_REMOVED], 0, session); +} + +static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, const gboolean success, gpointer data) +{ + OBEXManager *self = OBEXMANAGER(data); + + g_signal_emit(self, signals[TRANSFER_COMPLETED], 0, transfer, success); +} + +static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *transfer, gpointer data) +{ + OBEXManager *self = OBEXMANAGER(data); + + g_signal_emit(self, signals[TRANSFER_STARTED], 0, transfer); +} + diff --git a/src/lib/obexmanager.h b/src/lib/obexmanager.h new file mode 100644 index 0000000..bfdd12c --- /dev/null +++ b/src/lib/obexmanager.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 __OBEXMANAGER_H +#define __OBEXMANAGER_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXMANAGER_PATH "/" +#define BLUEZ_DBUS_OBEXMANAGER_INTERFACE "org.openobex.Manager" + +/* + * Type macros + */ +#define OBEXMANAGER_TYPE (obexmanager_get_type()) +#define OBEXMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXMANAGER_TYPE, OBEXManager)) +#define OBEXMANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXMANAGER_TYPE)) +#define OBEXMANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXMANAGER_TYPE, OBEXManagerClass)) +#define OBEXMANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXMANAGER_TYPE)) +#define OBEXMANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXMANAGER_TYPE, OBEXManagerClass)) + +typedef struct _OBEXManager OBEXManager; +typedef struct _OBEXManagerClass OBEXManagerClass; +typedef struct _OBEXManagerPrivate OBEXManagerPrivate; + +struct _OBEXManager { + GObject parent_instance; + + /*< private >*/ + OBEXManagerPrivate *priv; +}; + +struct _OBEXManagerClass { + GObjectClass parent_class; +}; + +/* used by OBEXMANAGER_TYPE */ +GType obexmanager_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +void obexmanager_register_agent(OBEXManager *self, const gchar *agent, GError **error); +void obexmanager_unregister_agent(OBEXManager *self, const gchar *agent, GError **error); + +#endif /* __OBEXMANAGER_H */ + diff --git a/src/lib/obexsession.c b/src/lib/obexsession.c new file mode 100644 index 0000000..ce482ab --- /dev/null +++ b/src/lib/obexsession.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 <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obexsession.h" + +#define OBEXSESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXSESSION_TYPE, OBEXSessionPrivate)) + +struct _OBEXSessionPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; + + /* Properties */ + gchar *address; +}; + +G_DEFINE_TYPE(OBEXSession, obexsession, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH, /* readwrite, construct only */ + PROP_ADDRESS /* readonly */ +}; + +static void _obexsession_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obexsession_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +static void obexsession_dispose(GObject *gobject) +{ + OBEXSession *self = OBEXSESSION(gobject); + + /* Properties free */ + g_free(self->priv->address); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obexsession_parent_class)->dispose(gobject); +} + +static void obexsession_class_init(OBEXSessionClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obexsession_dispose; + + g_type_class_add_private(klass, sizeof(OBEXSessionPrivate)); + + /* Properties registration */ + GParamSpec *pspec; + + gobject_class->get_property = _obexsession_get_property; + gobject_class->set_property = _obexsession_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + + /* string Address [readonly] */ + pspec = g_param_spec_string("Address", NULL, NULL, NULL, G_PARAM_READABLE); + g_object_class_install_property(gobject_class, PROP_ADDRESS, pspec); +} + +static void obexsession_init(OBEXSession *self) +{ + self->priv = OBEXSESSION_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void obexsession_post_init(OBEXSession *self, const gchar *dbus_object_path) +{ + g_assert(dbus_object_path != NULL); + g_assert(strlen(dbus_object_path) > 0); + g_assert(self->priv->dbus_g_proxy == NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXSESSION_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXSESSION_INTERFACE, dbus_object_path); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXSESSION_INTERFACE); + + /* Properties init */ + GHashTable *properties = obexsession_get_properties(self, &error); + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + g_assert(properties != NULL); + + /* string Address [readonly] */ + if (g_hash_table_lookup(properties, "Address")) { + self->priv->address = g_value_dup_string(g_hash_table_lookup(properties, "Address")); + } else { + self->priv->address = g_strdup("undefined"); + } + + g_hash_table_unref(properties); +} + +static void _obexsession_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + OBEXSession *self = OBEXSESSION(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obexsession_get_dbus_object_path(self)); + break; + + case PROP_ADDRESS: + g_value_set_string(value, obexsession_get_address(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obexsession_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + OBEXSession *self = OBEXSESSION(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + obexsession_post_init(self, g_value_get_string(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); +} + +/* Methods */ + +/* dict GetProperties() */ +GHashTable *obexsession_get_properties(OBEXSession *self, GError **error) +{ + g_assert(OBEXSESSION_IS(self)); + + GHashTable *ret = NULL; + dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetProperties", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID); + + return ret; +} + +/* Properties access methods */ +const gchar *obexsession_get_dbus_object_path(OBEXSession *self) +{ + g_assert(OBEXSESSION_IS(self)); + + return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); +} + +const gchar *obexsession_get_address(OBEXSession *self) +{ + g_assert(OBEXSESSION_IS(self)); + + return self->priv->address; +} + diff --git a/src/lib/obexsession.h b/src/lib/obexsession.h new file mode 100644 index 0000000..a6ecec7 --- /dev/null +++ b/src/lib/obexsession.h @@ -0,0 +1,68 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __OBEXSESSION_H +#define __OBEXSESSION_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXSESSION_INTERFACE "org.openobex.Session" + +/* + * Type macros + */ +#define OBEXSESSION_TYPE (obexsession_get_type()) +#define OBEXSESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXSESSION_TYPE, OBEXSession)) +#define OBEXSESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXSESSION_TYPE)) +#define OBEXSESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXSESSION_TYPE, OBEXSessionClass)) +#define OBEXSESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXSESSION_TYPE)) +#define OBEXSESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXSESSION_TYPE, OBEXSessionClass)) + +typedef struct _OBEXSession OBEXSession; +typedef struct _OBEXSessionClass OBEXSessionClass; +typedef struct _OBEXSessionPrivate OBEXSessionPrivate; + +struct _OBEXSession { + GObject parent_instance; + + /*< private >*/ + OBEXSessionPrivate *priv; +}; + +struct _OBEXSessionClass { + GObjectClass parent_class; +}; + +/* used by OBEXSESSION_TYPE */ +GType obexsession_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +GHashTable *obexsession_get_properties(OBEXSession *self, GError **error); + +const gchar *obexsession_get_dbus_object_path(OBEXSession *self); +const gchar *obexsession_get_address(OBEXSession *self); + +#endif /* __OBEXSESSION_H */ + diff --git a/src/lib/obextransfer.c b/src/lib/obextransfer.c new file mode 100644 index 0000000..2b94ee2 --- /dev/null +++ b/src/lib/obextransfer.c @@ -0,0 +1,210 @@ +/* + * + * bluez-tools - a set of tools to manage bluetooth devices for linux + * + * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> + +#include "dbus-common.h" +#include "marshallers.h" +#include "obextransfer.h" + +#define OBEXTRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXTRANSFER_TYPE, OBEXTransferPrivate)) + +struct _OBEXTransferPrivate { + DBusGProxy *dbus_g_proxy; + + /* Introspection data */ + DBusGProxy *introspection_g_proxy; + gchar *introspection_xml; +}; + +G_DEFINE_TYPE(OBEXTransfer, obextransfer, G_TYPE_OBJECT); + +enum { + PROP_0, + + PROP_DBUS_OBJECT_PATH /* readwrite, construct only */ +}; + +static void _obextransfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +static void _obextransfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); + +enum { + PROGRESS, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = {0}; + +static void progress_handler(DBusGProxy *dbus_g_proxy, const gint32 total, const gint32 transfered, gpointer data); + +static void obextransfer_dispose(GObject *gobject) +{ + OBEXTransfer *self = OBEXTRANSFER(gobject); + + /* DBus signals disconnection */ + dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Progress", G_CALLBACK(progress_handler), self); + + /* Proxy free */ + g_object_unref(self->priv->dbus_g_proxy); + + /* Introspection data free */ + g_free(self->priv->introspection_xml); + g_object_unref(self->priv->introspection_g_proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS(obextransfer_parent_class)->dispose(gobject); +} + +static void obextransfer_class_init(OBEXTransferClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = obextransfer_dispose; + + g_type_class_add_private(klass, sizeof(OBEXTransferPrivate)); + + /* Properties registration */ + GParamSpec *pspec; + + gobject_class->get_property = _obextransfer_get_property; + gobject_class->set_property = _obextransfer_set_property; + + /* object DBusObjectPath [readwrite, construct only] */ + pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec); + + /* Signals registation */ + signals[PROGRESS] = g_signal_new("Progress", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_bluez_marshal_VOID__INT_INT, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); +} + +static void obextransfer_init(OBEXTransfer *self) +{ + self->priv = OBEXTRANSFER_GET_PRIVATE(self); + + g_assert(conn != NULL); +} + +static void obextransfer_post_init(OBEXTransfer *self, const gchar *dbus_object_path) +{ + g_assert(dbus_object_path != NULL); + g_assert(strlen(dbus_object_path) > 0); + g_assert(self->priv->dbus_g_proxy == NULL); + + GError *error = NULL; + + /* Getting introspection XML */ + self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable"); + self->priv->introspection_xml = NULL; + if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) { + g_critical("%s", error->message); + } + g_assert(error == NULL); + + gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXTRANSFER_INTERFACE, "\">", NULL); + if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) { + g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXTRANSFER_INTERFACE, dbus_object_path); + g_assert(FALSE); + } + g_free(check_intf_regex_str); + self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXTRANSFER_INTERFACE); + + /* DBus signals connection */ + + /* Progress(int32 total, int32 transfered) */ + dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Progress", G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Progress", G_CALLBACK(progress_handler), self, NULL); +} + +static void _obextransfer_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + OBEXTransfer *self = OBEXTRANSFER(object); + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + g_value_set_string(value, obextransfer_get_dbus_object_path(self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void _obextransfer_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + OBEXTransfer *self = OBEXTRANSFER(object); + GError *error = NULL; + + switch (property_id) { + case PROP_DBUS_OBJECT_PATH: + obextransfer_post_init(self, g_value_get_string(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } + + if (error != NULL) { + g_critical("%s", error->message); + } + g_assert(error == NULL); +} + +/* Methods */ + +/* void Cancel() */ +void obextransfer_cancel(OBEXTransfer *self, GError **error) +{ + g_assert(OBEXTRANSFER_IS(self)); + + dbus_g_proxy_call(self->priv->dbus_g_proxy, "Cancel", error, G_TYPE_INVALID, G_TYPE_INVALID); +} + +/* Properties access methods */ +const gchar *obextransfer_get_dbus_object_path(OBEXTransfer *self) +{ + g_assert(OBEXTRANSFER_IS(self)); + + return dbus_g_proxy_get_path(self->priv->dbus_g_proxy); +} + +/* Signals handlers */ +static void progress_handler(DBusGProxy *dbus_g_proxy, const gint32 total, const gint32 transfered, gpointer data) +{ + OBEXTransfer *self = OBEXTRANSFER(data); + + g_signal_emit(self, signals[PROGRESS], 0, total, transfered); +} + diff --git a/src/lib/obextransfer.h b/src/lib/obextransfer.h new file mode 100644 index 0000000..1484d72 --- /dev/null +++ b/src/lib/obextransfer.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 __OBEXTRANSFER_H +#define __OBEXTRANSFER_H + +#include <glib-object.h> + +#define BLUEZ_DBUS_OBEXTRANSFER_INTERFACE "org.openobex.Transfer" + +/* + * Type macros + */ +#define OBEXTRANSFER_TYPE (obextransfer_get_type()) +#define OBEXTRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXTRANSFER_TYPE, OBEXTransfer)) +#define OBEXTRANSFER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXTRANSFER_TYPE)) +#define OBEXTRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXTRANSFER_TYPE, OBEXTransferClass)) +#define OBEXTRANSFER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXTRANSFER_TYPE)) +#define OBEXTRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXTRANSFER_TYPE, OBEXTransferClass)) + +typedef struct _OBEXTransfer OBEXTransfer; +typedef struct _OBEXTransferClass OBEXTransferClass; +typedef struct _OBEXTransferPrivate OBEXTransferPrivate; + +struct _OBEXTransfer { + GObject parent_instance; + + /*< private >*/ + OBEXTransferPrivate *priv; +}; + +struct _OBEXTransferClass { + GObjectClass parent_class; +}; + +/* used by OBEXTRANSFER_TYPE */ +GType obextransfer_get_type(void) G_GNUC_CONST; + +/* + * Method definitions + */ +void obextransfer_cancel(OBEXTransfer *self, GError **error); + +const gchar *obextransfer_get_dbus_object_path(OBEXTransfer *self); + +#endif /* __OBEXTRANSFER_H */ + diff --git a/src/lib/serial.c b/src/lib/serial.c index 8028e41..36f3746 100644 --- a/src/lib/serial.c +++ b/src/lib/serial.c @@ -25,6 +25,7 @@ #include <config.h> #endif +#include <glib.h> #include <string.h> #include "dbus-common.h" |