From: Bastien Nocera <hadess@hadess.net>
To: Tadas Dailyda <tadas@dailyda.com>
Cc: linux-bluetooth@vger.kernel.org
Subject: obex-data-server BlueZ 4.x patch
Date: Mon, 15 Sep 2008 15:56:52 +0100 [thread overview]
Message-ID: <1221490612.24928.307.camel@cookie.hadess.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 406 bytes --]
Heya,
Here's a patch to port obex-data-server to BlueZ 4.x. It drops support
for BIP devices though, as I have no example XML SDP record, or ways to
test.
The XML record parsing code is very naive, and could easily be made
stronger.
The latest version is also available at:
http://cvs.fedoraproject.org/viewvc/rpms/obex-data-server/devel/obex-data-server-0.4-bluez4.patch?view=markup
Comments?
Cheers
[-- Attachment #2: obex-data-server-0.4-bluez4.patch --]
[-- Type: text/x-patch, Size: 7163 bytes --]
Index: src/ods-bluez.c
===================================================================
--- src/ods-bluez.c (revision 1891)
+++ src/ods-bluez.c (working copy)
@@ -116,11 +116,11 @@
bluez->priv->manager_proxy = dbus_g_proxy_new_for_name (klass->connection,
"org.bluez",
- "/org/bluez",
+ "/",
"org.bluez.Manager");
if (!dbus_g_proxy_call (bluez->priv->manager_proxy, "DefaultAdapter", &error,
G_TYPE_INVALID,
- G_TYPE_STRING, &adapter_object,
+ DBUS_TYPE_G_OBJECT_PATH, &adapter_object,
G_TYPE_INVALID)) {
g_warning("Unable to connect to dbus: %s", error->message);
g_clear_error (&error);
@@ -326,7 +326,7 @@
g_clear_error (&error);
}
-
+#if 0
static void
get_remote_service_record_cb (DBusGProxy *proxy, DBusGProxyCall *call,
OdsBluezCancellable *cb_data)
@@ -349,7 +349,7 @@
goto err;
}
- sdp_record = sdp_extract_pdu ((uint8_t *)record_array->data, &scanned);
+ sdp_record = sdp_extract_pdu ((uint8_t *)record_array->data, record_array->len, &scanned);
/* get channel for this service */
if (sdp_get_access_protos (sdp_record, &protos) != 0) {
@@ -406,59 +406,135 @@
ods_bluez_cancellable_free (cb_data);
g_clear_error (&error);
}
+#endif
+typedef struct {
+ int channel;
+ gboolean in_attr;
+ gboolean done;
+} ctxdata;
+
static void
+record_parse_start_tag (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ctxdata *data = (ctxdata *) user_data;
+
+ if (data->done
+ || attribute_names == NULL
+ || attribute_values == NULL)
+ return;
+ if (g_str_equal (element_name, "attribute")
+ && g_str_equal (*attribute_names, "id")
+ && g_str_equal (*attribute_values, "0x0004")) {
+ data->in_attr = TRUE;
+ return;
+ }
+ if (!data->in_attr)
+ return;
+ if (g_str_equal (element_name, "uint8")
+ && g_str_equal (*attribute_names, "value")) {
+ double channel;
+ channel = g_ascii_strtod (*attribute_values, NULL);
+ data->channel = channel;
+ data->done = TRUE;
+ }
+}
+
+static gboolean
+parse_record (const char *record, int *ret_channel)
+{
+ GError *error = NULL;
+ GMarkupParseContext *ctx;
+ GMarkupParser parser = {
+ record_parse_start_tag, NULL, NULL, NULL, NULL
+ };
+ ctxdata *data;
+
+ data = g_new0 (ctxdata, 1);
+ data->channel = -1;
+
+ ctx = g_markup_parse_context_new (&parser, 0, data, NULL);
+
+ if (!g_markup_parse_context_parse (ctx, record, strlen (record), &error)) {
+ g_warning ("Couldn't parse service record: %s", error->message);
+ g_error_free (error);
+ g_markup_parse_context_free (ctx);
+ return FALSE;
+ }
+
+ if (data->channel != -1)
+ *ret_channel = data->channel;
+ return (data->channel != -1);
+}
+
+static void
get_remote_service_handles_cb (DBusGProxy *proxy, DBusGProxyCall *call,
OdsBluezCancellable *cb_data)
{
OdsBluezFunc cb = cb_data->cb;
gboolean ret;
GError *error = NULL;
- GArray *handle_array = NULL;
- guint32 service_handle = 0;
+ GHashTable *handle_hash = NULL;
+ GList *list, *l;
+ int channel;
ret = dbus_g_proxy_end_call (proxy, call, &error,
- DBUS_TYPE_G_UINT_ARRAY, &handle_array,
- G_TYPE_INVALID);
+ dbus_g_type_get_map ("GHashTable", G_TYPE_UINT, G_TYPE_STRING),
+ &handle_hash, G_TYPE_INVALID);
/* check if we were looking for Nokia specific FTP service and failed */
- if (ret && handle_array->len == 0 && !strcmp (cb_data->uuid, OBEX_NOKIAFTP_UUID)) {
+ if (ret && g_hash_table_size (handle_hash) == 0 && !strcmp (cb_data->uuid, OBEX_NOKIAFTP_UUID)) {
g_free (cb_data->uuid);
cb_data->uuid = g_strdup (OBEX_FTP_UUID);
cb_data->dbus_call = dbus_g_proxy_begin_call (proxy,
- "GetRemoteServiceHandles",
+ "DiscoverServices",
(DBusGProxyCallNotify) get_remote_service_handles_cb,
cb_data, NULL,
- G_TYPE_STRING, cb_data->target_address,
G_TYPE_STRING, cb_data->uuid,
G_TYPE_INVALID);
return;
}
/* service search failed */
- if (!ret || handle_array->len == 0) {
+ if (!ret || g_hash_table_size (handle_hash) == 0) {
g_clear_error (&error);
g_set_error (&error, ODS_ERROR, ODS_ERROR_CONNECTION_ATTEMPT_FAILED,
"Service search failed");
cb (-1, cb_data->imagingdata, error, cb_data->cb_data);
- ods_bluez_cancellable_free (cb_data);
g_clear_error (&error);
goto out;
}
- memcpy(&service_handle, handle_array->data, sizeof(service_handle));
+ channel = -1;
+ list = g_hash_table_get_values (handle_hash);
+ for (l = list; l != NULL; l = l->next) {
+ char *record = l->data;
+ if (parse_record (record, &channel) != FALSE) {
+ break;
+ }
+ }
+ g_list_free (list);
- /* Now get service record */
- cb_data->dbus_call = dbus_g_proxy_begin_call (proxy,
- "GetRemoteServiceRecord",
- (DBusGProxyCallNotify) get_remote_service_record_cb,
- cb_data, NULL,
- G_TYPE_STRING, cb_data->target_address,
- G_TYPE_UINT, service_handle,
- G_TYPE_INVALID);
+ if (channel != -1) {
+ rfcomm_connect (cb_data, channel);
+ g_object_unref (proxy);
+ g_hash_table_destroy (handle_hash);
+ return;
+ } else {
+ g_set_error (&error, ODS_ERROR, ODS_ERROR_FAILED,
+ "Could not get service channel");
+ cb (-1, cb_data->imagingdata, error, cb_data->cb_data);
+ g_clear_error (&error);
+ }
out:
- if (handle_array != NULL)
- g_array_free (handle_array, TRUE);
+ ods_bluez_cancellable_free (cb_data);
+ g_object_unref (proxy);
+ g_hash_table_destroy (handle_hash);
}
OdsBluezCancellable*
@@ -472,6 +548,7 @@
gpointer data)
{
OdsBluezCancellable *cb_data;
+ OdsBluezClass *klass = ODS_BLUEZ_GET_CLASS (bluez);
cb_data = g_new0 (OdsBluezCancellable, 1);
cb_data->cb = func;
@@ -496,12 +573,27 @@
/* Discover channel for needed service only if we don't know it yet */
if (channel == 0) {
+ char *device_path;
+ DBusGProxy *device;
+
+ if (dbus_g_proxy_call (bluez->priv->adapter_proxy, "FindDevice", NULL,
+ G_TYPE_STRING, cb_data->target_address, G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID) == FALSE) {
+ GError *error = NULL;
+ g_set_error (&error, ODS_ERROR, ODS_ERROR_CONNECTION_ATTEMPT_FAILED,
+ "Device not available");
+ func (-1, cb_data->imagingdata, error, cb_data->cb_data);
+ ods_bluez_cancellable_free (cb_data);
+ g_clear_error (&error);
+ return NULL;
+ }
+ device = dbus_g_proxy_new_for_name (klass->connection, "org.bluez", device_path, "org.bluez.Device");
+
/* find services that match our UUID */
- cb_data->dbus_call = dbus_g_proxy_begin_call (bluez->priv->adapter_proxy,
- "GetRemoteServiceHandles",
+ cb_data->dbus_call = dbus_g_proxy_begin_call (device,
+ "DiscoverServices",
(DBusGProxyCallNotify) get_remote_service_handles_cb,
cb_data, NULL,
- G_TYPE_STRING, cb_data->target_address,
G_TYPE_STRING, cb_data->uuid,
G_TYPE_INVALID);
} else {
reply other threads:[~2008-09-15 14:56 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1221490612.24928.307.camel@cookie.hadess.net \
--to=hadess@hadess.net \
--cc=linux-bluetooth@vger.kernel.org \
--cc=tadas@dailyda.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox