Diff between 05dc075e7d71aa3814366172c7c213b0369de74d and 04235bf3f764fed10303806526118d25e58d12b4

Changed Files

File Additions Deletions Status
obexd/client/main.c +93 -0 modified
obexd/client/session.c +16 -12 modified
obexd/client/session.h +2 -1 modified

Full Patch

diff --git a/obexd/client/main.c b/obexd/client/main.c
index 0ce274a..2e3ba95 100644
--- a/obexd/client/main.c
+++ b/obexd/client/main.c
@@ -309,6 +309,97 @@ static DBusMessage *create_session(DBusConnection *connection,
 	return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
 }
 
+static void capabilities_complete_callback(struct session_data *session,
+							void *user_data)
+{
+	struct send_data *data = user_data;
+	char *capabilities;
+
+	if (session->obex == NULL) {
+		DBusMessage *error = g_dbus_create_error(data->message,
+					"org.openobex.Error.Failed", NULL);
+		g_dbus_send_message(data->connection, error);
+		goto done;
+	}
+
+	capabilities = g_strndup(session->buffer, session->filled);
+
+	g_dbus_send_reply(data->connection, data->message,
+			DBUS_TYPE_STRING, &capabilities,
+			DBUS_TYPE_INVALID);
+
+	g_free(capabilities);
+
+done:
+
+	dbus_message_unref(data->message);
+	dbus_connection_unref(data->connection);
+	g_free(data->sender);
+	g_free(data);
+}
+
+static void capability_session_callback(struct session_data *session,
+							void *user_data)
+{
+	struct send_data *data = user_data;
+
+	if (session->obex == NULL) {
+		DBusMessage *error = g_dbus_create_error(data->message,
+					"org.openobex.Error.Failed", NULL);
+		g_dbus_send_message(data->connection, error);
+		goto done;
+	}
+
+	session_pull(session, "x-obex/capability", NULL,
+				capabilities_complete_callback, data);
+
+	return;
+
+done:
+	dbus_message_unref(data->message);
+	dbus_connection_unref(data->connection);
+	g_free(data->sender);
+	g_free(data);
+}
+
+static DBusMessage *get_capabilities(DBusConnection *connection,
+					DBusMessage *message, void *user_data)
+{
+	DBusMessageIter iter, dict;
+	struct send_data *data;
+	const char *source = NULL, *dest = NULL, *target = NULL;
+
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &dict);
+
+	parse_device_dict(&dict, &source, &dest, &target);
+	if (dest == NULL)
+		return g_dbus_create_error(message,
+				"org.openobex.Error.InvalidArguments", NULL);
+
+	data = g_try_malloc0(sizeof(*data));
+	if (data == NULL)
+		return g_dbus_create_error(message,
+					"org.openobex.Error.NoMemory", NULL);
+
+	data->connection = dbus_connection_ref(connection);
+	data->message = dbus_message_ref(message);
+	data->sender = g_strdup(dbus_message_get_sender(message));
+
+	if (!target)
+		target = "OPP";
+
+	if (session_create(source, dest, target, capability_session_callback, data) == 0)
+		return NULL;
+
+	dbus_message_unref(data->message);
+	dbus_connection_unref(data->connection);
+	g_free(data->sender);
+	g_free(data);
+
+	return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
+}
+
 static GDBusMethodTable client_methods[] = {
 	{ "SendFiles", "a{sv}aso", "", send_files,
 						G_DBUS_METHOD_FLAG_ASYNC },
@@ -318,6 +409,8 @@ static GDBusMethodTable client_methods[] = {
 						G_DBUS_METHOD_FLAG_ASYNC },
 	{ "CreateSession", "a{sv}", "o", create_session,
 						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "GetCapabilities", "a{sv}", "s", get_capabilities,
+						G_DBUS_METHOD_FLAG_ASYNC },
 	{ }
 };
 
diff --git a/obexd/client/session.c b/obexd/client/session.c
index 0a6decc..7e6be3b 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -56,6 +56,10 @@
 
 static guint64 counter = 0;
 
+static unsigned char pcsuite_uuid[] = { 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+					0x10, 0x00, 0x80, 0x00, 0x00, 0x02,
+					0xEE, 0x00, 0x00, 0x01 };
+
 struct callback_data {
 	struct session_data *session;
 	sdp_session_t *sdp;
@@ -109,7 +113,7 @@ static void session_unref(struct session_data *session)
 			g_dbus_unregister_interface(session->conn,
 					session->transfer_path, TRANSFER_INTERFACE);
 
-		switch (session->uuid) {
+		switch (session->uuid.value.uuid16) {
 		case OBEX_FILETRANS_SVCLASS_ID:
 			g_dbus_unregister_interface(session->conn,
 					session->path,	FTP_INTERFACE);
@@ -311,7 +315,6 @@ static gboolean service_callback(GIOChannel *io, GIOCondition cond,
 	struct callback_data *callback = user_data;
 	sdp_list_t *search, *attrid;
 	uint32_t range = 0x0000ffff;
-	uuid_t uuid;
 
 	if (cond & (G_IO_NVAL | G_IO_ERR))
 		goto failed;
@@ -319,9 +322,7 @@ static gboolean service_callback(GIOChannel *io, GIOCondition cond,
 	if (sdp_set_notify(callback->sdp, search_callback, callback) < 0)
 		goto failed;
 
-	sdp_uuid16_create(&uuid, callback->session->uuid);
-
-	search = sdp_list_append(NULL, &uuid);
+	search = sdp_list_append(NULL, &callback->session->uuid);
 	attrid = sdp_list_append(NULL, &range);
 
 	if (sdp_service_search_attr_async(callback->sdp,
@@ -404,15 +405,17 @@ int session_create(const char *source,
 	str2ba(destination, &session->dst);
 
 	if (!g_ascii_strncasecmp(target, "OPP", 3)) {
-		session->uuid = OBEX_OBJPUSH_SVCLASS_ID;
+		sdp_uuid16_create(&session->uuid, OBEX_OBJPUSH_SVCLASS_ID);
 	} else if (!g_ascii_strncasecmp(target, "FTP", 3)) {
-		session->uuid = OBEX_FILETRANS_SVCLASS_ID;
+		sdp_uuid16_create(&session->uuid, OBEX_FILETRANS_SVCLASS_ID);
 		session->target = OBEX_FTP_UUID;
 		session->target_len = OBEX_FTP_UUID_LEN;
 	} else if (!g_ascii_strncasecmp(target, "PBAP", 4)) {
-		session->uuid = PBAP_PSE_SVCLASS_ID;
+		sdp_uuid16_create(&session->uuid, PBAP_PSE_SVCLASS_ID);
 		session->target = OBEX_PBAP_UUID;
 		session->target_len = OBEX_PBAP_UUID_LEN;
+	} else if (!g_ascii_strncasecmp(target, "PCSUITE", 7)) {
+		sdp_uuid128_create(&session->uuid, pcsuite_uuid);
 	} else {
 		return -EINVAL;
 	}
@@ -1090,9 +1093,10 @@ complete:
 				session->filled);
 		agent_notify_complete(session->conn, session->agent_name,
 				session->agent_path, session->transfer_path);
-
-		callback->func(callback->session, callback->data);
 	}
+
+	callback->func(callback->session, callback->data);
+
 	unregister_transfer(session);
 
 	session_unref(callback->session);
@@ -1577,7 +1581,7 @@ int session_pull(struct session_data *session,
 	if (xfer == NULL)
 		return -ENOTCONN;
 
-	gw_obex_xfer_set_callback(xfer, get_xfer_progress, callback);
+	gw_obex_xfer_set_callback(xfer, get_xfer_listing_progress, callback);
 
 	session->xfer = xfer;
 
@@ -1596,7 +1600,7 @@ int session_register(struct session_data *session)
 					NULL, NULL, session, NULL) == FALSE)
 		return -EIO;
 
-	switch (session->uuid) {
+	switch (session->uuid.value.uuid16) {
 	case OBEX_FILETRANS_SVCLASS_ID:
 		result = g_dbus_register_interface(session->conn,
 					session->path, FTP_INTERFACE,
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 1af2503..b91fc58 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -25,6 +25,7 @@
 #include <gdbus.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
 #include <gw-obex.h>
 
 struct session_data {
@@ -34,7 +35,7 @@ struct session_data {
 	uint8_t channel;
 	const char *target;	/* OBEX Target UUID */
 	int target_len;
-	uint16_t uuid;		/* Bluetooth Service Class */
+	uuid_t uuid;		/* Bluetooth Service Class */
 	gchar *name;
 	gchar *path;		/* Session path */
 	gchar *transfer_path;	/* Transfer path */