obexd: Introduce GetCapabilities support to client API.

This commit is contained in:
Luiz Augusto von Dentz 2008-12-24 10:35:29 -03:00 committed by Marcel Holtmann
parent 05dc075e7d
commit 04235bf3f7
3 changed files with 111 additions and 13 deletions

View File

@ -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 },
{ }
};

View File

@ -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,

View File

@ -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 */