mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-15 06:55:30 +08:00
obexd: Introduce GetCapabilities support to client API.
This commit is contained in:
parent
05dc075e7d
commit
04235bf3f7
@ -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 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user