* [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated
@ 2011-07-18 10:35 Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 2/6] client: make session structure private Luiz Augusto von Dentz
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:35 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This avoid having to iterate twice in the list to free its elements.
---
plugins/bluetooth.c | 8 +++-----
plugins/pbap.c | 7 ++++---
plugins/phonebook-dummy.c | 3 +--
plugins/phonebook-tracker.c | 5 ++---
plugins/vcard.c | 17 +++++------------
5 files changed, 15 insertions(+), 25 deletions(-)
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index b126717..0c50a54 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -546,7 +546,7 @@ static void *bluetooth_start(struct obex_server *server, int *err)
return ios;
}
-static void stop(gpointer data, gpointer user_data)
+static void stop(gpointer data)
{
GIOChannel *io = data;
@@ -558,8 +558,7 @@ static void bluetooth_stop(void *data)
{
GSList *ios = data;
- g_slist_foreach(ios, stop, NULL);
- g_slist_free(ios);
+ g_slist_free_full(ios, stop);
}
static struct obex_transport_driver driver = {
@@ -589,8 +588,7 @@ static void bluetooth_exit(void)
g_dbus_remove_watch(connection, listener_id);
if (any) {
- g_slist_foreach(any->services, (GFunc) g_free, NULL);
- g_slist_free(any->services);
+ g_slist_free_full(any->services, g_free);
g_free(any->path);
g_free(any);
}
diff --git a/plugins/pbap.c b/plugins/pbap.c
index 5455cce..1925b5f 100644
--- a/plugins/pbap.c
+++ b/plugins/pbap.c
@@ -160,8 +160,10 @@ static const uint8_t PBAP_TARGET[TARGET_SIZE] = {
typedef int (*cache_entry_find_f) (const struct cache_entry *entry,
const char *value);
-static void cache_entry_free(struct cache_entry *entry)
+static void cache_entry_free(void *data)
{
+ struct cache_entry *entry = data;
+
g_free(entry->id);
g_free(entry->name);
g_free(entry->sound);
@@ -222,8 +224,7 @@ static const char *cache_find(struct cache *cache, uint32_t handle)
static void cache_clear(struct cache *cache)
{
- g_slist_foreach(cache->entries, (GFunc) cache_entry_free, NULL);
- g_slist_free(cache->entries);
+ g_slist_free_full(cache->entries, cache_entry_free);
cache->entries = NULL;
}
diff --git a/plugins/phonebook-dummy.c b/plugins/phonebook-dummy.c
index ede4643..035ec35 100644
--- a/plugins/phonebook-dummy.c
+++ b/plugins/phonebook-dummy.c
@@ -186,8 +186,7 @@ static int foreach_vcard(DIR *dp, vcard_func_t func, uint16_t offset,
close(fd);
}
- g_slist_foreach(sorted, (GFunc) g_free, NULL);
- g_slist_free(sorted);
+ g_slist_free_full(sorted, g_free);
if (count)
*count = n;
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index d1f4cd7..2ff2056 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1442,15 +1442,14 @@ static gboolean find_checked_number(GSList *numbers, const char *number)
return FALSE;
}
-static void gstring_free_helper(gpointer data, gpointer user_data)
+static void gstring_free_helper(gpointer data)
{
g_string_free(data, TRUE);
}
static void free_data_numbers(struct phonebook_data *data)
{
- g_slist_foreach(data->numbers, gstring_free_helper, NULL);
- g_slist_free(data->numbers);
+ g_slist_free_full(data->numbers, gstring_free_helper);
data->numbers = NULL;
}
diff --git a/plugins/vcard.c b/plugins/vcard.c
index b997fc4..490d258 100644
--- a/plugins/vcard.c
+++ b/plugins/vcard.c
@@ -599,7 +599,7 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
}
-static void field_free(gpointer data, gpointer user_data)
+static void field_free(gpointer data)
{
struct phonebook_field *field = data;
@@ -612,17 +612,10 @@ void phonebook_contact_free(struct phonebook_contact *contact)
if (contact == NULL)
return;
- g_slist_foreach(contact->numbers, field_free, NULL);
- g_slist_free(contact->numbers);
-
- g_slist_foreach(contact->emails, field_free, NULL);
- g_slist_free(contact->emails);
-
- g_slist_foreach(contact->addresses, field_free, NULL);
- g_slist_free(contact->addresses);
-
- g_slist_foreach(contact->urls, field_free, NULL);
- g_slist_free(contact->urls);
+ g_slist_free_full(contact->numbers, field_free);
+ g_slist_free_full(contact->emails, field_free);
+ g_slist_free_full(contact->addresses, field_free);
+ g_slist_free_full(contact->urls, field_free);
g_free(contact->uid);
g_free(contact->fullname);
--
1.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH obexd 2/6] client: make session structure private
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
@ 2011-07-18 10:35 ` Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 3/6] client: make transfer " Luiz Augusto von Dentz
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:35 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
Session data should not be acessible directly otherwise it cause too
much dependency by profile specific code which is quite inefficient in
the long term.
---
client/main.c | 25 +++--
client/pbap.c | 284 ++++++++++++++++++++++++++++++-----------------------
client/pbap.h | 14 +---
client/session.c | 118 ++++++++++++++++------
client/session.h | 45 +++------
client/sync.c | 86 +++++++++-------
client/sync.h | 5 +-
client/transfer.c | 30 ++++--
client/transfer.h | 1 +
9 files changed, 351 insertions(+), 257 deletions(-)
diff --git a/client/main.c b/client/main.c
index 478181c..18f4d2f 100644
--- a/client/main.c
+++ b/client/main.c
@@ -61,11 +61,15 @@ static void shutdown_session(struct session_data *session)
session_unref(session);
}
-static void owner_exit(DBusConnection *connection, void *user_data)
+static void unregister_session(void *data)
{
- struct session_data *session = user_data;
+ struct session_data *session = data;
- shutdown_session(session);
+ if (g_slist_find(sessions, session) == NULL)
+ return;
+
+ sessions = g_slist_remove(sessions, session);
+ session_unref(session);
}
static void create_callback(struct session_data *session, GError *err,
@@ -83,12 +87,13 @@ static void create_callback(struct session_data *session, GError *err,
goto done;
}
- if (session->target != NULL) {
- session_register(session);
- session_set_owner(session, data->sender, owner_exit);
+ if (session_get_target(session) != NULL) {
+ const char *path;
+
+ path = session_register(session, unregister_session);
g_dbus_send_reply(data->connection, data->message,
- DBUS_TYPE_OBJECT_PATH, &session->path,
+ DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
goto done;
}
@@ -351,7 +356,7 @@ static struct session_data *find_session(const char *path)
for (l = sessions; l; l = l->next) {
struct session_data *session = l->data;
- if (g_str_equal(session->path, path) == TRUE)
+ if (g_str_equal(session_get_path(session), path) == TRUE)
return session;
}
@@ -417,7 +422,7 @@ static DBusMessage *remove_session(DBusConnection *connection,
"org.openobex.Error.InvalidArguments", NULL);
sender = dbus_message_get_sender(message);
- if (g_str_equal(sender, session->owner) == FALSE)
+ if (g_str_equal(sender, session_get_owner(session)) == FALSE)
return g_dbus_create_error(message,
"org.openobex.Error.NotAuthorized",
"Not Authorized");
@@ -430,7 +435,7 @@ static DBusMessage *remove_session(DBusConnection *connection,
static void capabilities_complete_callback(struct session_data *session,
GError *err, void *user_data)
{
- struct transfer_data *transfer = session->pending->data;
+ struct transfer_data *transfer = session_get_transfer(session);
struct send_data *data = user_data;
char *capabilities;
diff --git a/client/pbap.c b/client/pbap.c
index 589b1ca..a7017bd 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -112,6 +112,18 @@ static const char *filter_list[] = {
#define FILTER_BIT_MAX 63
#define FILTER_ALL 0xFFFFFFFFFFFFFFFFULL
+#define PBAP_INTERFACE "org.openobex.PhonebookAccess"
+
+struct pbap_data {
+ struct session_data *session;
+ char *path;
+ DBusConnection *conn;
+ DBusMessage *msg;
+ guint8 format;
+ guint8 order;
+ uint64_t filter;
+};
+
struct pullphonebook_apparam {
uint8_t filter_tag;
uint8_t filter_len;
@@ -218,38 +230,38 @@ static gchar *build_phonebook_path(const char *location, const char *item)
}
/* should only be called inside pbap_set_path */
-static void pbap_reset_path(struct session_data *session)
+static void pbap_reset_path(struct pbap_data *pbap)
{
int err = 0;
char **paths = NULL, **item;
- struct pbap_data *pbapdata = session_get_data(session);
+ GwObex *obex = session_get_obex(pbap->session);
- if (!pbapdata->path)
+ if (!pbap->path)
return;
- gw_obex_chdir(session->obex, "", &err);
+ gw_obex_chdir(obex, "", &err);
- paths = g_strsplit(pbapdata->path, "/", 3);
+ paths = g_strsplit(pbap->path, "/", 3);
for (item = paths; *item; item++)
- gw_obex_chdir(session->obex, *item, &err);
+ gw_obex_chdir(obex, *item, &err);
g_strfreev(paths);
}
-static gint pbap_set_path(struct session_data *session, const char *path)
+static gint pbap_set_path(struct pbap_data *pbap, const char *path)
{
int err = 0;
char **paths = NULL, **item;
- struct pbap_data *pbapdata = session_get_data(session);
+ GwObex *obex = session_get_obex(pbap->session);
if (!path)
return OBEX_RSP_BAD_REQUEST;
- if (pbapdata->path != NULL && g_str_equal(pbapdata->path, path))
+ if (pbap->path != NULL && g_str_equal(pbap->path, path))
return 0;
- if (gw_obex_chdir(session->obex, "", &err) == FALSE) {
+ if (gw_obex_chdir(obex, "", &err) == FALSE) {
if (err == OBEX_RSP_NOT_IMPLEMENTED)
goto done;
goto fail;
@@ -257,9 +269,9 @@ static gint pbap_set_path(struct session_data *session, const char *path)
paths = g_strsplit(path, "/", 3);
for (item = paths; *item; item++) {
- if (gw_obex_chdir(session->obex, *item, &err) == FALSE) {
+ if (gw_obex_chdir(obex, *item, &err) == FALSE) {
/* we need to reset the path to the saved one on fail*/
- pbap_reset_path(session);
+ pbap_reset_path(pbap);
goto fail;
}
}
@@ -267,8 +279,8 @@ static gint pbap_set_path(struct session_data *session, const char *path)
g_strfreev(paths);
done:
- g_free(pbapdata->path);
- pbapdata->path = g_strdup(path);
+ g_free(pbap->path);
+ pbap->path = g_strdup(path);
return 0;
fail:
@@ -281,7 +293,7 @@ fail:
static void read_return_apparam(struct session_data *session,
guint16 *phone_book_size, guint8 *new_missed_calls)
{
- struct transfer_data *transfer = session->pending->data;
+ struct transfer_data *transfer = session_get_transfer(session);
GwObexXfer *xfer = transfer->xfer;
unsigned char *buf;
size_t size = 0;
@@ -333,14 +345,22 @@ static void read_return_apparam(struct session_data *session,
static void pull_phonebook_callback(struct session_data *session,
GError *err, void *user_data)
{
- struct transfer_data *transfer = session->pending->data;
+ struct transfer_data *transfer = session_get_transfer(session);
+ struct pbap_data *pbap = user_data;
DBusMessage *reply;
char *buf = "";
- if (session->msg == NULL)
+ if (pbap->msg == NULL)
goto done;
- reply = dbus_message_new_method_return(session->msg);
+ if (err) {
+ reply = g_dbus_create_error(pbap->msg,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ goto send;
+ }
+
+ reply = dbus_message_new_method_return(pbap->msg);
if (transfer->filled > 0)
buf = transfer->buffer;
@@ -350,9 +370,11 @@ static void pull_phonebook_callback(struct session_data *session,
DBUS_TYPE_INVALID);
transfer->filled = 0;
- g_dbus_send_message(session->conn, reply);
- dbus_message_unref(session->msg);
- session->msg = NULL;
+
+send:
+ g_dbus_send_message(pbap->conn, reply);
+ dbus_message_unref(pbap->msg);
+ pbap->msg = NULL;
done:
transfer_unregister(transfer);
@@ -361,15 +383,23 @@ done:
static void phonebook_size_callback(struct session_data *session,
GError *err, void *user_data)
{
- struct transfer_data *transfer = session->pending->data;
+ struct transfer_data *transfer = session_get_transfer(session);
+ struct pbap_data *pbap = user_data;
DBusMessage *reply;
guint16 phone_book_size;
guint8 new_missed_calls;
- if (session->msg == NULL)
+ if (pbap->msg == NULL)
goto done;
- reply = dbus_message_new_method_return(session->msg);
+ if (err) {
+ reply = g_dbus_create_error(pbap->msg,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ goto send;
+ }
+
+ reply = dbus_message_new_method_return(pbap->msg);
read_return_apparam(session, &phone_book_size, &new_missed_calls);
@@ -378,9 +408,11 @@ static void phonebook_size_callback(struct session_data *session,
DBUS_TYPE_INVALID);
transfer->filled = 0;
- g_dbus_send_message(session->conn, reply);
- dbus_message_unref(session->msg);
- session->msg = NULL;
+
+send:
+ g_dbus_send_message(pbap->conn, reply);
+ dbus_message_unref(pbap->msg);
+ pbap->msg = NULL;
done:
transfer_unregister(transfer);
@@ -389,19 +421,27 @@ done:
static void pull_vcard_listing_callback(struct session_data *session,
GError *err, void *user_data)
{
- struct transfer_data *transfer = session->pending->data;
+ struct transfer_data *transfer = session_get_transfer(session);
+ struct pbap_data *pbap = user_data;
GMarkupParseContext *ctxt;
DBusMessage *reply;
DBusMessageIter iter, array;
int i;
- if (session->msg == NULL)
+ if (pbap->msg == NULL)
goto complete;
- reply = dbus_message_new_method_return(session->msg);
+ if (err) {
+ reply = g_dbus_create_error(pbap->msg,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ goto send;
+ }
+
+ reply = dbus_message_new_method_return(pbap->msg);
if (transfer->filled == 0)
- goto done;
+ goto send;
for (i = transfer->filled - 1; i > 0; i--) {
if (transfer->buffer[i] != '\0')
@@ -423,15 +463,15 @@ static void pull_vcard_listing_callback(struct session_data *session,
transfer->filled = 0;
-done:
- g_dbus_send_message(session->conn, reply);
- dbus_message_unref(session->msg);
- session->msg = NULL;
+send:
+ g_dbus_send_message(pbap->conn, reply);
+ dbus_message_unref(pbap->msg);
+ pbap->msg = NULL;
complete:
transfer_unregister(transfer);
}
-static DBusMessage *pull_phonebook(struct session_data *session,
+static DBusMessage *pull_phonebook(struct pbap_data *pbap,
DBusMessage *message, guint8 type,
const char *name, uint64_t filter,
guint8 format, guint16 maxlistcount,
@@ -440,7 +480,7 @@ static DBusMessage *pull_phonebook(struct session_data *session,
struct pullphonebook_apparam apparam;
session_callback_t func;
- if (session->msg)
+ if (pbap->msg)
return g_dbus_create_error(message,
"org.openobex.Error.InProgress",
"Transfer in progress");
@@ -470,14 +510,14 @@ static DBusMessage *pull_phonebook(struct session_data *session,
return NULL;
}
- if (session_get(session, "x-bt/phonebook", name, NULL,
+ if (session_get(pbap->session, "x-bt/phonebook", name, NULL,
(guint8 *) &apparam, sizeof(apparam),
- func) < 0)
+ func, pbap) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");
- session->msg = dbus_message_ref(message);
+ pbap->msg = dbus_message_ref(message);
return NULL;
}
@@ -494,7 +534,7 @@ static guint8 *fill_apparam(guint8 *dest, void *buf, guint8 tag, guint8 len)
return dest;
}
-static DBusMessage *pull_vcard_listing(struct session_data *session,
+static DBusMessage *pull_vcard_listing(struct pbap_data *pbap,
DBusMessage *message, const char *name,
guint8 order, char *searchval, guint8 attrib,
guint16 count, guint16 offset)
@@ -503,7 +543,7 @@ static DBusMessage *pull_vcard_listing(struct session_data *session,
gint apparam_size;
int err;
- if (session->msg)
+ if (pbap->msg)
return g_dbus_create_error(message,
"org.openobex.Error.InProgress",
"Transfer in progress");
@@ -534,53 +574,50 @@ static DBusMessage *pull_vcard_listing(struct session_data *session,
offset = GUINT16_TO_BE(offset);
p = fill_apparam(p, &offset, LISTSTARTOFFSET_TAG, LISTSTARTOFFSET_LEN);
- err = session_get(session, "x-bt/vcard-listing", name, NULL,
- apparam, apparam_size, pull_vcard_listing_callback);
+ err = session_get(pbap->session, "x-bt/vcard-listing", name, NULL,
+ apparam, apparam_size,
+ pull_vcard_listing_callback, pbap);
g_free(apparam);
if (err < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");
- session->msg = dbus_message_ref(message);
+ pbap->msg = dbus_message_ref(message);
return NULL;
}
-static int set_format(struct session_data *session, const char *formatstr)
+static int set_format(struct pbap_data *pbap, const char *formatstr)
{
- struct pbap_data *pbapdata = session_get_data(session);
-
if (!formatstr || g_str_equal(formatstr, "")) {
- pbapdata->format = FORMAT_VCARD21;
+ pbap->format = FORMAT_VCARD21;
return 0;
}
if (!g_ascii_strcasecmp(formatstr, "vcard21"))
- pbapdata->format = FORMAT_VCARD21;
+ pbap->format = FORMAT_VCARD21;
else if (!g_ascii_strcasecmp(formatstr, "vcard30"))
- pbapdata->format = FORMAT_VCARD30;
+ pbap->format = FORMAT_VCARD30;
else
return -EINVAL;
return 0;
}
-static int set_order(struct session_data *session, const char *orderstr)
+static int set_order(struct pbap_data *pbap, const char *orderstr)
{
- struct pbap_data *pbapdata = session_get_data(session);
-
if (!orderstr || g_str_equal(orderstr, "")) {
- pbapdata->order = ORDER_INDEXED;
+ pbap->order = ORDER_INDEXED;
return 0;
}
if (!g_ascii_strcasecmp(orderstr, "indexed"))
- pbapdata->order = ORDER_INDEXED;
+ pbap->order = ORDER_INDEXED;
else if (!g_ascii_strcasecmp(orderstr, "alphanumeric"))
- pbapdata->order = ORDER_ALPHANUMERIC;
+ pbap->order = ORDER_ALPHANUMERIC;
else if (!g_ascii_strcasecmp(orderstr, "phonetic"))
- pbapdata->order = ORDER_PHONETIC;
+ pbap->order = ORDER_PHONETIC;
else
return -EINVAL;
@@ -612,9 +649,8 @@ static uint64_t get_filter_mask(const char *filterstr)
return 0;
}
-static int add_filter(struct session_data *session, const char *filterstr)
+static int add_filter(struct pbap_data *pbap, const char *filterstr)
{
- struct pbap_data *pbapdata = session_get_data(session);
uint64_t mask;
mask = get_filter_mask(filterstr);
@@ -622,13 +658,12 @@ static int add_filter(struct session_data *session, const char *filterstr)
if (mask == 0)
return -EINVAL;
- pbapdata->filter |= mask;
+ pbap->filter |= mask;
return 0;
}
-static int remove_filter(struct session_data *session, const char *filterstr)
+static int remove_filter(struct pbap_data *pbap, const char *filterstr)
{
- struct pbap_data *pbapdata = session_get_data(session);
uint64_t mask;
mask = get_filter_mask(filterstr);
@@ -636,7 +671,7 @@ static int remove_filter(struct session_data *session, const char *filterstr)
if (mask == 0)
return -EINVAL;
- pbapdata->filter &= ~mask;
+ pbap->filter &= ~mask;
return 0;
}
@@ -669,7 +704,7 @@ static gchar **get_filter_strs(uint64_t filter, gint *size)
static DBusMessage *pbap_select(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
+ struct pbap_data *pbap = user_data;
const char *item, *location;
char *path = NULL;
int err = 0;
@@ -686,7 +721,7 @@ static DBusMessage *pbap_select(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", "InvalidPhonebook");
- err = pbap_set_path(session, path);
+ err = pbap_set_path(pbap, path);
g_free(path);
if (err)
return g_dbus_create_error(message,
@@ -699,19 +734,18 @@ static DBusMessage *pbap_select(DBusConnection *connection,
static DBusMessage *pbap_pull_all(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
DBusMessage * err;
char *name;
- if (!pbapdata->path)
+ if (!pbap->path)
return g_dbus_create_error(message,
ERROR_INF ".Forbidden", "Call Select first of all");
- name = g_strconcat(pbapdata->path, ".vcf", NULL);
+ name = g_strconcat(pbap->path, ".vcf", NULL);
- err = pull_phonebook(session, message, PULLPHONEBOOK, name,
- pbapdata->filter, pbapdata->format,
+ err = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
+ pbap->filter, pbap->format,
DEFAULT_COUNT, DEFAULT_OFFSET);
g_free(name);
return err;
@@ -720,12 +754,11 @@ static DBusMessage *pbap_pull_all(DBusConnection *connection,
static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
struct pullvcardentry_apparam apparam;
const char *name;
- if (!pbapdata->path)
+ if (!pbap->path)
return g_dbus_create_error(message,
ERROR_INF ".Forbidden",
"Call Select first of all");
@@ -736,26 +769,26 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
- if (session->msg)
+ if (pbap->msg)
return g_dbus_create_error(message,
"org.openobex.Error.InProgress",
"Transfer in progress");
apparam.filter_tag = FILTER_TAG;
apparam.filter_len = FILTER_LEN;
- apparam.filter = GUINT64_TO_BE(pbapdata->filter);
+ apparam.filter = GUINT64_TO_BE(pbap->filter);
apparam.format_tag = FORMAT_TAG;
apparam.format_len = FORMAT_LEN;
- apparam.format = pbapdata->format;
+ apparam.format = pbap->format;
- if (session_get(session, "x-bt/vcard", name, NULL,
+ if (session_get(pbap->session, "x-bt/vcard", name, NULL,
(guint8 *)&apparam, sizeof(apparam),
- pull_phonebook_callback) < 0)
+ pull_phonebook_callback, pbap) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");
- session->msg = dbus_message_ref(message);
+ pbap->msg = dbus_message_ref(message);
return NULL;
}
@@ -763,22 +796,20 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
static DBusMessage *pbap_list(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
- if (!pbapdata->path)
+ if (!pbap->path)
return g_dbus_create_error(message,
ERROR_INF ".Forbidden", "Call Select first of all");
- return pull_vcard_listing(session, message, "", pbapdata->order, "",
+ return pull_vcard_listing(pbap, message, "", pbap->order, "",
ATTRIB_NAME, DEFAULT_COUNT, DEFAULT_OFFSET);
}
static DBusMessage *pbap_search(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
char *field, *value;
guint8 attrib;
@@ -789,7 +820,7 @@ static DBusMessage *pbap_search(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
- if (!pbapdata->path)
+ if (!pbap->path)
return g_dbus_create_error(message,
ERROR_INF ".Forbidden", "Call Select first of all");
@@ -805,27 +836,26 @@ static DBusMessage *pbap_search(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
- return pull_vcard_listing(session, message, "", pbapdata->order, value,
- attrib, DEFAULT_COUNT, DEFAULT_OFFSET);
+ return pull_vcard_listing(pbap, message, "", pbap->order, value,
+ attrib, DEFAULT_COUNT, DEFAULT_OFFSET);
}
static DBusMessage *pbap_get_size(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
DBusMessage * err;
char *name;
- if (!pbapdata->path)
+ if (!pbap->path)
return g_dbus_create_error(message,
ERROR_INF ".Forbidden", "Call Select first of all");
- name = g_strconcat(pbapdata->path, ".vcf", NULL);
+ name = g_strconcat(pbap->path, ".vcf", NULL);
- err = pull_phonebook(session, message, GETPHONEBOOKSIZE, name,
- pbapdata->filter, pbapdata->format,
- 0, DEFAULT_OFFSET);
+ err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name,
+ pbap->filter, pbap->format, 0,
+ DEFAULT_OFFSET);
g_free(name);
return err;
}
@@ -833,7 +863,7 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,
static DBusMessage *pbap_set_format(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
+ struct pbap_data *pbap = user_data;
const char *format;
if (dbus_message_get_args(message, NULL,
@@ -842,7 +872,7 @@ static DBusMessage *pbap_set_format(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
- if (set_format(session, format) < 0)
+ if (set_format(pbap, format) < 0)
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", "InvalidFormat");
@@ -852,7 +882,7 @@ static DBusMessage *pbap_set_format(DBusConnection *connection,
static DBusMessage *pbap_set_order(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
+ struct pbap_data *pbap = user_data;
const char *order;
if (dbus_message_get_args(message, NULL,
@@ -861,7 +891,7 @@ static DBusMessage *pbap_set_order(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
- if (set_order(session, order) < 0)
+ if (set_order(pbap, order) < 0)
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", "InvalidFilter");
@@ -871,11 +901,10 @@ static DBusMessage *pbap_set_order(DBusConnection *connection,
static DBusMessage *pbap_set_filter(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
char **filters, **item;
gint size;
- uint64_t oldfilter = pbapdata->filter;
+ uint64_t oldfilter = pbap->filter;
if (dbus_message_get_args(message, NULL, DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING, &filters, &size,
@@ -883,13 +912,13 @@ static DBusMessage *pbap_set_filter(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
- remove_filter(session, "ALL");
+ remove_filter(pbap, "ALL");
if (size == 0)
goto done;
for (item = filters; *item; item++) {
- if (add_filter(session, *item) < 0) {
- pbapdata->filter = oldfilter;
+ if (add_filter(pbap, *item) < 0) {
+ pbap->filter = oldfilter;
g_strfreev(filters);
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", "InvalidFilters");
@@ -904,13 +933,12 @@ done:
static DBusMessage *pbap_get_filter(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct pbap_data *pbapdata = session_get_data(session);
+ struct pbap_data *pbap = user_data;
gchar **filters = NULL;
gint size;
DBusMessage *reply;
- filters = get_filter_strs(pbapdata->filter, &size);
+ filters = get_filter_strs(pbap->filter, &size);
reply = dbus_message_new_method_return(message);
dbus_message_append_args(reply, DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING, &filters, size,
@@ -957,28 +985,38 @@ static GDBusMethodTable pbap_methods[] = {
{ }
};
+static void pbap_free(void *data)
+{
+ struct pbap_data *pbap = data;
+
+ session_unref(pbap->session);
+ dbus_connection_unref(pbap->conn);
+ g_free(pbap);
+}
+
gboolean pbap_register_interface(DBusConnection *connection, const char *path,
- void *user_data, GDBusDestroyFunction destroy)
+ void *user_data)
{
struct session_data *session = user_data;
- void *priv;
+ struct pbap_data *pbap;
- priv = g_try_malloc0(sizeof(struct pbap_data));
- if (!priv)
+ pbap = g_try_new0(struct pbap_data, 1);
+ if (!pbap)
return FALSE;
- session_set_data(session, priv);
+ pbap->session = session_ref(session);
+ pbap->conn = dbus_connection_ref(connection);
+
+ if (g_dbus_register_interface(connection, path, PBAP_INTERFACE,
+ pbap_methods, NULL, NULL, pbap, pbap_free) == FALSE) {
+ pbap_free(pbap);
+ return FALSE;
+ }
- return g_dbus_register_interface(connection, path, PBAP_INTERFACE,
- pbap_methods, NULL, NULL, user_data, destroy);
+ return TRUE;
}
-void pbap_unregister_interface(DBusConnection *connection, const char *path,
- void *user_data)
+void pbap_unregister_interface(DBusConnection *connection, const char *path)
{
- struct session_data *session = user_data;
- void *priv = session_get_data(session);
-
g_dbus_unregister_interface(connection, path, PBAP_INTERFACE);
- g_free(priv);
}
diff --git a/client/pbap.h b/client/pbap.h
index 8fae116..3ae1159 100644
--- a/client/pbap.h
+++ b/client/pbap.h
@@ -24,16 +24,6 @@
#include <gdbus.h>
-#define PBAP_INTERFACE "org.openobex.PhonebookAccess"
-
-struct pbap_data {
- char *path;
- guint8 format;
- guint8 order;
- uint64_t filter;
-};
-
gboolean pbap_register_interface(DBusConnection *connection, const char *path,
- void *user_data, GDBusDestroyFunction destroy);
-void pbap_unregister_interface(DBusConnection *connection, const char *path,
- void *user_data);
\ No newline at end of file
+ void *user_data);
+void pbap_unregister_interface(DBusConnection *connection, const char *path);
diff --git a/client/session.c b/client/session.c
index 36475d6..64bcb78 100644
--- a/client/session.c
+++ b/client/session.c
@@ -97,6 +97,31 @@ struct pending_req {
void *user_data;
};
+struct session_data {
+ gint refcount;
+ bdaddr_t src;
+ bdaddr_t dst;
+ uint8_t channel;
+ char *service; /* Service friendly name */
+ const char *target; /* OBEX Target UUID */
+ int target_len;
+ uuid_t uuid; /* Bluetooth Service Class */
+ gchar *path; /* Session path */
+ DBusConnection *conn;
+ DBusConnection *conn_system; /* system bus connection */
+ DBusMessage *msg;
+ GwObex *obex;
+ GIOChannel *io;
+ struct agent_data *agent;
+ struct session_callback *callback;
+ gchar *owner; /* Session owner */
+ guint watch;
+ GSList *pending;
+ GSList *pending_calls;
+ void *priv;
+ char *adapter;
+};
+
static GSList *sessions = NULL;
static void session_prepare_put(struct session_data *session, GError *err,
@@ -163,27 +188,28 @@ static void agent_release(struct session_data *session)
static void session_unregistered(struct session_data *session)
{
+ char *path;
+
switch (session->uuid.value.uuid16) {
case OBEX_FILETRANS_SVCLASS_ID:
g_dbus_unregister_interface(session->conn, session->path,
FTP_INTERFACE);
break;
case PBAP_PSE_SVCLASS_ID:
- pbap_unregister_interface(session->conn, session->path,
- session);
+ pbap_unregister_interface(session->conn, session->path);
break;
case IRMC_SYNC_SVCLASS_ID:
- sync_unregister_interface(session->conn, session->path,
- session);
+ sync_unregister_interface(session->conn, session->path);
}
- g_dbus_unregister_interface(session->conn, session->path,
- SESSION_INTERFACE);
+ path = session->path;
+ session->path = NULL;
- DBG("Session(%p) unregistered %s", session, session->path);
+ g_dbus_unregister_interface(session->conn, path, SESSION_INTERFACE);
- g_free(session->path);
- session->path = NULL;
+ DBG("Session(%p) unregistered %s", session, path);
+
+ g_free(path);
}
static struct pending_req *find_session_request(
@@ -1408,7 +1434,7 @@ static void session_prepare_get(struct session_data *session,
int session_get(struct session_data *session, const char *type,
const char *filename, const char *targetname,
const guint8 *apparam, gint apparam_size,
- session_callback_t func)
+ session_callback_t func, void *user_data)
{
struct transfer_data *transfer;
struct transfer_params *params = NULL;
@@ -1438,6 +1464,7 @@ int session_get(struct session_data *session, const char *type,
struct session_callback *callback;
callback = g_new0(struct session_callback, 1);
callback->func = func;
+ callback->data = user_data;
session->callback = callback;
}
@@ -1502,7 +1529,7 @@ static DBusMessage *list_folder(DBusConnection *connection,
"Transfer in progress");
if (session_get(session, "x-obex/folder-listing",
- NULL, NULL, NULL, 0, list_folder_callback) < 0)
+ NULL, NULL, NULL, 0, list_folder_callback, NULL) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");
@@ -1531,7 +1558,7 @@ static DBusMessage *get_file(DBusConnection *connection,
"org.openobex.Error.InvalidArguments", NULL);
if (session_get(session, NULL, source_file,
- target_file, NULL, 0, get_file_callback) < 0)
+ target_file, NULL, 0, get_file_callback, NULL) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");
@@ -1672,17 +1699,21 @@ int session_pull(struct session_data *session,
return err;
}
-int session_register(struct session_data *session)
+const char *session_register(struct session_data *session,
+ GDBusDestroyFunction destroy)
{
gboolean result = FALSE;
+ if (session->path)
+ return session->path;
+
session->path = g_strdup_printf("%s/session%ju",
SESSION_BASEPATH, counter++);
if (g_dbus_register_interface(session->conn, session->path,
SESSION_INTERFACE, session_methods,
- NULL, NULL, session, NULL) == FALSE)
- return -EIO;
+ NULL, NULL, session, destroy) == FALSE)
+ goto fail;
switch (session->uuid.value.uuid16) {
case OBEX_FILETRANS_SVCLASS_ID:
@@ -1691,33 +1722,28 @@ int session_register(struct session_data *session)
ftp_methods, NULL, NULL, session, NULL);
break;
case PBAP_PSE_SVCLASS_ID:
- result = pbap_register_interface(session->conn,
- session->path, session, NULL);
+ result = pbap_register_interface(session->conn, session->path,
+ session);
break;
case IRMC_SYNC_SVCLASS_ID:
- result = sync_register_interface(session->conn,
- session->path, session, NULL);
+ result = sync_register_interface(session->conn, session->path,
+ session);
}
if (result == FALSE) {
g_dbus_unregister_interface(session->conn,
session->path, SESSION_INTERFACE);
- return -EIO;
+ goto fail;
}
DBG("Session(%p) registered %s", session, session->path);
- return 0;
-}
+ return session->path;
-void *session_get_data(struct session_data *session)
-{
- return session->priv;
-}
-
-void session_set_data(struct session_data *session, void *priv)
-{
- session->priv = priv;
+fail:
+ g_free(session->path);
+ session->path = NULL;
+ return NULL;
}
static void session_prepare_put(struct session_data *session,
@@ -1813,3 +1839,35 @@ const char *session_get_owner(struct session_data *session)
return session->owner;
}
+
+const char *session_get_path(struct session_data *session)
+{
+ return session->path;
+}
+
+const char *session_get_target(struct session_data *session)
+{
+ return session->target;
+}
+
+GwObex *session_get_obex(struct session_data *session)
+{
+ return session->obex;
+}
+
+struct transfer_data *session_get_transfer(struct session_data *session)
+{
+ return session->pending ? session->pending->data : NULL;
+}
+
+void session_add_transfer(struct session_data *session,
+ struct transfer_data *transfer)
+{
+ session->pending = g_slist_append(session->pending, transfer);
+}
+
+void session_remove_transfer(struct session_data *session,
+ struct transfer_data *transfer)
+{
+ session->pending = g_slist_remove(session->pending, transfer);
+}
diff --git a/client/session.h b/client/session.h
index 39f5742..081a2c3 100644
--- a/client/session.h
+++ b/client/session.h
@@ -28,33 +28,7 @@
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
-struct agent_data;
-struct session_callback;
-
-struct session_data {
- gint refcount;
- bdaddr_t src;
- bdaddr_t dst;
- uint8_t channel;
- char *service; /* Service friendly name */
- const char *target; /* OBEX Target UUID */
- int target_len;
- uuid_t uuid; /* Bluetooth Service Class */
- gchar *path; /* Session path */
- DBusConnection *conn;
- DBusConnection *conn_system; /* system bus connection */
- DBusMessage *msg;
- GwObex *obex;
- GIOChannel *io;
- struct agent_data *agent;
- struct session_callback *callback;
- gchar *owner; /* Session owner */
- guint watch;
- GSList *pending;
- GSList *pending_calls;
- void *priv;
- char *adapter;
-};
+struct session_data;
typedef void (*session_callback_t) (struct session_data *session,
GError *err, void *user_data);
@@ -79,17 +53,26 @@ int session_set_agent(struct session_data *session, const char *name,
const char *path);
const char *session_get_agent(struct session_data *session);
+const char *session_get_path(struct session_data *session);
+const char *session_get_target(struct session_data *session);
+GwObex *session_get_obex(struct session_data *session);
+
+struct transfer_data *session_get_transfer(struct session_data *session);
+void session_add_transfer(struct session_data *session,
+ struct transfer_data *transfer);
+void session_remove_transfer(struct session_data *session,
+ struct transfer_data *transfer);
+
int session_send(struct session_data *session, const char *filename,
const char *remotename);
int session_get(struct session_data *session, const char *type,
const char *filename, const char *targetname,
const guint8 *apparam, gint apparam_size,
- session_callback_t func);
+ session_callback_t func, void *user_data);
int session_pull(struct session_data *session,
const char *type, const char *filename,
session_callback_t function, void *user_data);
-int session_register(struct session_data *session);
-void *session_get_data(struct session_data *session);
-void session_set_data(struct session_data *session, void *priv);
+const char *session_register(struct session_data *session,
+ GDBusDestroyFunction destroy);
int session_put(struct session_data *session, char *buf,
const char *targetname);
diff --git a/client/sync.c b/client/sync.c
index 3622a3d..9271bf3 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -37,14 +37,16 @@
#define ERROR_INF SYNC_INTERFACE ".Error"
struct sync_data {
+ struct session_data *session;
char *phonebook_path;
+ DBusConnection *conn;
+ DBusMessage *msg;
};
static DBusMessage *sync_setlocation(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct sync_data *syncdata = session_get_data(session);
+ struct sync_data *sync = user_data;
const char *location;
char *path = NULL, *tmp;
@@ -65,8 +67,8 @@ static DBusMessage *sync_setlocation(DBusConnection *connection,
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", "InvalidPhonebook");
- g_free(syncdata->phonebook_path);
- syncdata->phonebook_path = path;
+ g_free(sync->phonebook_path);
+ sync->phonebook_path = path;
return dbus_message_new_method_return(message);
}
@@ -74,11 +76,12 @@ static DBusMessage *sync_setlocation(DBusConnection *connection,
static void sync_getphonebook_callback(struct session_data *session,
GError *err, void *user_data)
{
- struct transfer_data *transfer = session->pending->data;
+ struct transfer_data *transfer = session_get_transfer(session);
+ struct sync_data *sync = user_data;
DBusMessage *reply;
char *buf = NULL;
- reply = dbus_message_new_method_return(session->msg);
+ reply = dbus_message_new_method_return(sync->msg);
if (transfer->filled > 0)
buf = transfer->buffer;
@@ -88,31 +91,30 @@ static void sync_getphonebook_callback(struct session_data *session,
DBUS_TYPE_INVALID);
transfer->filled = 0;
- g_dbus_send_message(session->conn, reply);
- dbus_message_unref(session->msg);
- session->msg = NULL;
+ g_dbus_send_message(sync->conn, reply);
+ dbus_message_unref(sync->msg);
+ sync->msg = NULL;
}
static DBusMessage *sync_getphonebook(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct sync_data *syncdata = session_get_data(session);
+ struct sync_data *sync = user_data;
- if (session->msg)
+ if (sync->msg)
return g_dbus_create_error(message,
ERROR_INF ".InProgress", "Transfer in progress");
/* set default phonebook_path to memory internal phonebook */
- if (!syncdata->phonebook_path)
- syncdata->phonebook_path = g_strdup("telecom/pb.vcf");
+ if (!sync->phonebook_path)
+ sync->phonebook_path = g_strdup("telecom/pb.vcf");
- if (session_get(session, "phonebook", syncdata->phonebook_path, NULL,
- NULL, 0, sync_getphonebook_callback) < 0)
+ if (session_get(sync->session, "phonebook", sync->phonebook_path, NULL,
+ NULL, 0, sync_getphonebook_callback, sync) < 0)
return g_dbus_create_error(message,
ERROR_INF ".Failed", "Failed");
- session->msg = dbus_message_ref(message);
+ sync->msg = dbus_message_ref(message);
return NULL;
}
@@ -120,8 +122,7 @@ static DBusMessage *sync_getphonebook(DBusConnection *connection,
static DBusMessage *sync_putphonebook(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- struct session_data *session = user_data;
- struct sync_data *syncdata = session_get_data(session);
+ struct sync_data *sync = user_data;
const char *buf;
char *buffer;
@@ -132,12 +133,12 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
ERROR_INF ".InvalidArguments", NULL);
/* set default phonebook_path to memory internal phonebook */
- if (!syncdata->phonebook_path)
- syncdata->phonebook_path = g_strdup("telecom/pb.vcf");
+ if (!sync->phonebook_path)
+ sync->phonebook_path = g_strdup("telecom/pb.vcf");
buffer = g_strdup(buf);
- if (session_put(session, buffer, syncdata->phonebook_path) < 0)
+ if (session_put(sync->session, buffer, sync->phonebook_path) < 0)
return g_dbus_create_error(message,
ERROR_INF ".Failed", "Failed");
@@ -153,32 +154,39 @@ static GDBusMethodTable sync_methods[] = {
{}
};
+static void sync_free(void *data)
+{
+ struct sync_data *sync = data;
+
+ session_unref(sync->session);
+ dbus_connection_unref(sync->conn);
+ g_free(sync->phonebook_path);
+ g_free(sync);
+}
+
gboolean sync_register_interface(DBusConnection *connection, const char *path,
- void *user_data, GDBusDestroyFunction destroy)
+ void *user_data)
{
struct session_data *session = user_data;
- void *priv;
+ struct sync_data *sync;
- priv = g_try_malloc0(sizeof(struct sync_data));
- if (!priv)
+ sync = g_try_new0(struct sync_data, 1);
+ if (!sync)
return FALSE;
- session_set_data(session, priv);
+ sync->session = session_ref(session);
+ sync->conn = dbus_connection_ref(connection);
- return g_dbus_register_interface(connection, path, SYNC_INTERFACE,
- sync_methods, NULL, NULL, user_data, destroy);
+ if (g_dbus_register_interface(connection, path, SYNC_INTERFACE,
+ sync_methods, NULL, NULL, sync, sync_free)) {
+ sync_free(sync);
+ return FALSE;
+ }
+
+ return TRUE;
}
-void sync_unregister_interface(DBusConnection *connection, const char *path,
- void *user_data)
+void sync_unregister_interface(DBusConnection *connection, const char *path)
{
- struct session_data *session = user_data;
- struct sync_data *syncdata = session_get_data(session);
-
g_dbus_unregister_interface(connection, path, SYNC_INTERFACE);
-
- if (syncdata) {
- g_free(syncdata->phonebook_path);
- g_free(syncdata);
- }
}
diff --git a/client/sync.h b/client/sync.h
index 5f9c483..01806e6 100644
--- a/client/sync.h
+++ b/client/sync.h
@@ -25,6 +25,5 @@
#include <gdbus.h>
gboolean sync_register_interface(DBusConnection *connection, const char *path,
- void *user_data, GDBusDestroyFunction destroy);
-void sync_unregister_interface(DBusConnection *connection, const char *path,
- void *user_data);
+ void *user_data);
+void sync_unregister_interface(DBusConnection *connection, const char *path);
diff --git a/client/transfer.c b/client/transfer.c
index fdcaa46..9e6f0ad 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -156,7 +156,7 @@ static void transfer_free(struct transfer_data *transfer)
if (transfer->fd > 0)
close(transfer->fd);
- session->pending = g_slist_remove(session->pending, transfer);
+ session_remove_transfer(session, transfer);
session_unref(session);
@@ -165,6 +165,9 @@ static void transfer_free(struct transfer_data *transfer)
g_free(transfer->params);
}
+ if (transfer->conn)
+ dbus_connection_unref(transfer->conn);
+
g_free(transfer->callback);
g_free(transfer->filename);
g_free(transfer->name);
@@ -198,7 +201,13 @@ struct transfer_data *transfer_register(struct session_data *session,
transfer->path = g_strdup_printf("%s/transfer%ju",
TRANSFER_BASEPATH, counter++);
- if (g_dbus_register_interface(session->conn, transfer->path,
+ transfer->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (transfer->conn == NULL) {
+ transfer_free(transfer);
+ return NULL;
+ }
+
+ if (g_dbus_register_interface(transfer->conn, transfer->path,
TRANSFER_INTERFACE,
transfer_methods, NULL, NULL,
transfer, NULL) == FALSE) {
@@ -209,17 +218,15 @@ struct transfer_data *transfer_register(struct session_data *session,
done:
DBG("%p registered %s", transfer, transfer->path);
- session->pending = g_slist_append(session->pending, transfer);
+ session_add_transfer(session, transfer);
return transfer;
}
void transfer_unregister(struct transfer_data *transfer)
{
- struct session_data *session = transfer->session;
-
if (transfer->path) {
- g_dbus_unregister_interface(session->conn,
+ g_dbus_unregister_interface(transfer->conn,
transfer->path, TRANSFER_INTERFACE);
}
@@ -420,6 +427,7 @@ int transfer_get(struct transfer_data *transfer, transfer_callback_t func,
void *user_data)
{
struct session_data *session = transfer->session;
+ GwObex *obex;
gw_obex_xfer_cb_t cb;
if (transfer->xfer != NULL)
@@ -441,15 +449,17 @@ int transfer_get(struct transfer_data *transfer, transfer_callback_t func,
cb = get_xfer_progress;
}
+ obex = session_get_obex(session);
+
if (transfer->params != NULL)
- transfer->xfer = gw_obex_get_async_with_apparam(session->obex,
+ transfer->xfer = gw_obex_get_async_with_apparam(obex,
transfer->filename,
transfer->type,
transfer->params->data,
transfer->params->size,
NULL);
else
- transfer->xfer = gw_obex_get_async(session->obex,
+ transfer->xfer = gw_obex_get_async(obex,
transfer->filename,
transfer->type,
NULL);
@@ -468,6 +478,7 @@ int transfer_put(struct transfer_data *transfer, transfer_callback_t func,
void *user_data)
{
struct session_data *session = transfer->session;
+ GwObex *obex;
gw_obex_xfer_cb_t cb;
struct stat st;
int fd, size;
@@ -497,8 +508,9 @@ int transfer_put(struct transfer_data *transfer, transfer_callback_t func,
cb = put_xfer_progress;
done:
+ obex = session_get_obex(session);
size = transfer->size < UINT32_MAX ? transfer->size : 0;
- transfer->xfer = gw_obex_put_async(session->obex, transfer->name,
+ transfer->xfer = gw_obex_put_async(obex, transfer->name,
transfer->type, size,
-1, NULL);
if (transfer->xfer == NULL)
diff --git a/client/transfer.h b/client/transfer.h
index 500232b..7392267 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -34,6 +34,7 @@ struct transfer_data {
struct session_data *session;
struct transfer_params *params;
struct transfer_callback *callback;
+ DBusConnection *conn;
char *path; /* Transfer path */
gchar *filename; /* Transfer file location */
char *name; /* Transfer object name */
--
1.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH obexd 3/6] client: make transfer structure private
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 2/6] client: make session structure private Luiz Augusto von Dentz
@ 2011-07-18 10:35 ` Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 4/6] client: separate ftp code from session Luiz Augusto von Dentz
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:35 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This make it easier to modularize obex-client
---
client/main.c | 9 +++--
client/pbap.c | 42 +++++++++++---------------
client/session.c | 86 ++++++++++++++++++++++++++++++-----------------------
client/sync.c | 9 +++--
client/transfer.c | 72 +++++++++++++++++++++++++++++++++++++++++++-
client/transfer.h | 37 +++++++++-------------
6 files changed, 162 insertions(+), 93 deletions(-)
diff --git a/client/main.c b/client/main.c
index 18f4d2f..19ca436 100644
--- a/client/main.c
+++ b/client/main.c
@@ -437,7 +437,8 @@ static void capabilities_complete_callback(struct session_data *session,
{
struct transfer_data *transfer = session_get_transfer(session);
struct send_data *data = user_data;
- char *capabilities;
+ const char *capabilities;
+ int size;
if (err != NULL) {
DBusMessage *error = g_dbus_create_error(data->message,
@@ -447,14 +448,14 @@ static void capabilities_complete_callback(struct session_data *session,
goto done;
}
- capabilities = g_strndup(transfer->buffer, transfer->filled);
+ capabilities = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ capabilities = "";
g_dbus_send_reply(data->connection, data->message,
DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
- g_free(capabilities);
-
done:
shutdown_session(session);
diff --git a/client/pbap.c b/client/pbap.c
index a7017bd..38d5a47 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -294,23 +294,21 @@ static void read_return_apparam(struct session_data *session,
guint16 *phone_book_size, guint8 *new_missed_calls)
{
struct transfer_data *transfer = session_get_transfer(session);
- GwObexXfer *xfer = transfer->xfer;
+ struct transfer_params params;
unsigned char *buf;
size_t size = 0;
*phone_book_size = 0;
*new_missed_calls = 0;
- if (xfer == NULL)
+ if (transfer_get_params(transfer, ¶ms) < 0)
return;
- buf = gw_obex_xfer_object_apparam(xfer, &size);
-
- if (size < APPARAM_HDR_SIZE)
+ if (params.size < APPARAM_HDR_SIZE)
return;
while (size > APPARAM_HDR_SIZE) {
- struct apparam_hdr *hdr = (struct apparam_hdr *) buf;
+ struct apparam_hdr *hdr = (struct apparam_hdr *) params.data;
if (hdr->len > size - APPARAM_HDR_SIZE) {
error("Unexpected PBAP pullphonebook app"
@@ -348,7 +346,8 @@ static void pull_phonebook_callback(struct session_data *session,
struct transfer_data *transfer = session_get_transfer(session);
struct pbap_data *pbap = user_data;
DBusMessage *reply;
- char *buf = "";
+ const char *buf;
+ int size;
if (pbap->msg == NULL)
goto done;
@@ -362,14 +361,15 @@ static void pull_phonebook_callback(struct session_data *session,
reply = dbus_message_new_method_return(pbap->msg);
- if (transfer->filled > 0)
- buf = transfer->buffer;
+ buf = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ buf = "";
dbus_message_append_args(reply,
DBUS_TYPE_STRING, &buf,
DBUS_TYPE_INVALID);
- transfer->filled = 0;
+ transfer_clear_buffer(transfer);
send:
g_dbus_send_message(pbap->conn, reply);
@@ -407,7 +407,7 @@ static void phonebook_size_callback(struct session_data *session,
DBUS_TYPE_UINT16, &phone_book_size,
DBUS_TYPE_INVALID);
- transfer->filled = 0;
+ transfer_clear_buffer(transfer);
send:
g_dbus_send_message(pbap->conn, reply);
@@ -426,7 +426,8 @@ static void pull_vcard_listing_callback(struct session_data *session,
GMarkupParseContext *ctxt;
DBusMessage *reply;
DBusMessageIter iter, array;
- int i;
+ const char *buf;
+ int size;
if (pbap->msg == NULL)
goto complete;
@@ -440,15 +441,9 @@ static void pull_vcard_listing_callback(struct session_data *session,
reply = dbus_message_new_method_return(pbap->msg);
- if (transfer->filled == 0)
- goto send;
-
- for (i = transfer->filled - 1; i > 0; i--) {
- if (transfer->buffer[i] != '\0')
- break;
-
- transfer->filled--;
- }
+ buf = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ buf = "";
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
@@ -456,12 +451,11 @@ static void pull_vcard_listing_callback(struct session_data *session,
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
DBUS_STRUCT_END_CHAR_AS_STRING, &array);
ctxt = g_markup_parse_context_new(&listing_parser, 0, &array, NULL);
- g_markup_parse_context_parse(ctxt, transfer->buffer,
- transfer->filled, NULL);
+ g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
g_markup_parse_context_free(ctxt);
dbus_message_iter_close_container(&iter, &array);
- transfer->filled = 0;
+ transfer_clear_buffer(transfer);
send:
g_dbus_send_message(pbap->conn, reply);
diff --git a/client/session.c b/client/session.c
index 64bcb78..8ad9a49 100644
--- a/client/session.c
+++ b/client/session.c
@@ -82,6 +82,7 @@ struct session_callback {
struct pending_data {
DBusPendingCall *call;
session_callback_t cb;
+ struct session_data *session;
struct transfer_data *transfer;
};
@@ -1118,19 +1119,20 @@ static void list_folder_callback(struct session_data *session,
GMarkupParseContext *ctxt;
DBusMessage *reply;
DBusMessageIter iter, array;
- int i;
-
- reply = dbus_message_new_method_return(session->msg);
+ const char *buf;
+ int size;
- if (transfer->filled == 0)
+ if (err != NULL) {
+ reply = g_dbus_create_error(session->msg,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
goto done;
+ } else
+ reply = dbus_message_new_method_return(session->msg);
- for (i = transfer->filled - 1; i > 0; i--) {
- if (transfer->buffer[i] != '\0')
- break;
-
- transfer->filled--;
- }
+ buf = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ buf = "";
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
@@ -1139,12 +1141,11 @@ static void list_folder_callback(struct session_data *session,
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
ctxt = g_markup_parse_context_new(&parser, 0, &array, NULL);
- g_markup_parse_context_parse(ctxt, transfer->buffer,
- transfer->filled, NULL);
+ g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
g_markup_parse_context_free(ctxt);
dbus_message_iter_close_container(&iter, &array);
- transfer->filled = 0;
+ transfer_clear_buffer(transfer);
done:
g_dbus_send_message(session->conn, reply);
@@ -1190,10 +1191,8 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
DBG("Agent.Request() reply: %s", name);
- if (strlen(name)) {
- g_free(pending->transfer->name);
- pending->transfer->name = g_strdup(name);
- }
+ if (strlen(name))
+ transfer_set_name(pending->transfer, name);
agent->pending = NULL;
@@ -1209,7 +1208,7 @@ static gboolean session_request_proceed(gpointer data)
struct pending_data *pending = data;
struct transfer_data *transfer = pending->transfer;
- pending->cb(transfer->session, NULL, transfer);
+ pending->cb(pending->session, NULL, transfer);
free_pending(pending);
return FALSE;
@@ -1221,12 +1220,16 @@ static int session_request(struct session_data *session, session_callback_t cb,
struct agent_data *agent = session->agent;
DBusMessage *message;
struct pending_data *pending;
+ const char *path;
pending = g_new0(struct pending_data, 1);
pending->cb = cb;
+ pending->session = session;
pending->transfer = transfer;
- if (agent == NULL || transfer->path == NULL) {
+ path = transfer_get_path(transfer);
+
+ if (agent == NULL || path == NULL) {
g_idle_add(session_request_proceed, pending);
return 0;
}
@@ -1235,7 +1238,7 @@ static int session_request(struct session_data *session, session_callback_t cb,
agent->path, AGENT_INTERFACE, "Request");
dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &transfer->path,
+ DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
if (!dbus_connection_send_with_reply(session->conn, message,
@@ -1251,7 +1254,7 @@ static int session_request(struct session_data *session, session_callback_t cb,
dbus_pending_call_set_notify(pending->call, session_request_reply,
session, NULL);
- DBG("Agent.Request(\"%s\")", transfer->path);
+ DBG("Agent.Request(\"%s\")", path);
return 0;
}
@@ -1283,8 +1286,11 @@ static void session_notify_complete(struct session_data *session,
{
struct agent_data *agent = session->agent;
DBusMessage *message;
+ const char *path;
+
+ path = transfer_get_path(transfer);
- if (agent == NULL || transfer->path == NULL)
+ if (agent == NULL || path == NULL)
goto done;
message = dbus_message_new_method_call(agent->name,
@@ -1295,7 +1301,7 @@ static void session_notify_complete(struct session_data *session,
dbus_message_set_no_reply(message, TRUE);
dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &transfer->path,
+ DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
g_dbus_send_message(session->conn, message);
@@ -1313,6 +1319,7 @@ static void session_notify_error(struct session_data *session,
{
struct agent_data *agent = session->agent;
DBusMessage *message;
+ const char *path;
if (session->msg) {
DBusMessage *reply;
@@ -1326,7 +1333,8 @@ static void session_notify_error(struct session_data *session,
session->msg = NULL;
}
- if (agent == NULL || transfer->path == NULL)
+ path = transfer_get_path(transfer);
+ if (agent == NULL || path == NULL)
goto done;
message = dbus_message_new_method_call(agent->name,
@@ -1337,7 +1345,7 @@ static void session_notify_error(struct session_data *session,
dbus_message_set_no_reply(message, TRUE);
dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &transfer->path,
+ DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_STRING, &err->message,
DBUS_TYPE_INVALID);
@@ -1355,9 +1363,11 @@ static void session_notify_progress(struct session_data *session,
{
struct agent_data *agent = session->agent;
DBusMessage *message;
+ const char *path;
/* For GetFile reply on the first received stream */
- if (transfer->fd > 0 && session->msg) {
+ if (session->msg &&
+ dbus_message_has_member(session->msg, "GetFile")) {
DBusMessage *reply;
reply = dbus_message_new_method_return(session->msg);
@@ -1367,7 +1377,8 @@ static void session_notify_progress(struct session_data *session,
session->msg = NULL;
}
- if (agent == NULL || transfer->path == NULL)
+ path = transfer_get_path(transfer);
+ if (agent == NULL || path == NULL)
goto done;
message = dbus_message_new_method_call(agent->name,
@@ -1378,7 +1389,7 @@ static void session_notify_progress(struct session_data *session,
dbus_message_set_no_reply(message, TRUE);
dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &transfer->path,
+ DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_UINT64, &transferred,
DBUS_TYPE_INVALID);
@@ -1388,7 +1399,7 @@ done:
DBG("Transfer(%p) progress: %ld bytes", transfer,
(long int ) transferred);
- if (transferred == transfer->size)
+ if (transferred == transfer_get_size(transfer))
session_notify_complete(session, transfer);
}
@@ -1450,8 +1461,8 @@ int session_get(struct session_data *session, const char *type,
params->size = apparam_size;
}
- transfer = transfer_register(session, filename, targetname, type,
- params);
+ transfer = transfer_register(session->conn, filename, targetname, type,
+ params, session);
if (transfer == NULL) {
if (params != NULL) {
g_free(params->data);
@@ -1647,8 +1658,8 @@ int session_send(struct session_data *session, const char *filename,
if (session->obex == NULL)
return -ENOTCONN;
- transfer = transfer_register(session, filename, targetname, NULL,
- NULL);
+ transfer = transfer_register(session->conn, filename, targetname, NULL,
+ NULL, session);
if (transfer == NULL)
return -EINVAL;
@@ -1678,7 +1689,8 @@ int session_pull(struct session_data *session,
if (session->obex == NULL)
return -ENOTCONN;
- transfer = transfer_register(session, NULL, filename, type, NULL);
+ transfer = transfer_register(session->conn, NULL, filename, type, NULL,
+ session);
if (transfer == NULL) {
return -EIO;
}
@@ -1777,12 +1789,12 @@ int session_put(struct session_data *session, char *buf, const char *targetname)
if (session->pending != NULL)
return -EISCONN;
- transfer = transfer_register(session, NULL, targetname, NULL, NULL);
+ transfer = transfer_register(session->conn, NULL, targetname, NULL,
+ NULL, session);
if (transfer == NULL)
return -EIO;
- transfer->size = strlen(buf);
- transfer->buffer = buf;
+ transfer_set_buffer(transfer, buf);
err = session_request(session, session_prepare_put, transfer);
if (err < 0)
diff --git a/client/sync.c b/client/sync.c
index 9271bf3..d9b6af7 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -79,18 +79,19 @@ static void sync_getphonebook_callback(struct session_data *session,
struct transfer_data *transfer = session_get_transfer(session);
struct sync_data *sync = user_data;
DBusMessage *reply;
- char *buf = NULL;
+ const char *buf;
+ int size;
reply = dbus_message_new_method_return(sync->msg);
- if (transfer->filled > 0)
- buf = transfer->buffer;
+ buf = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ buf = "";
dbus_message_append_args(reply,
DBUS_TYPE_STRING, &buf,
DBUS_TYPE_INVALID);
- transfer->filled = 0;
g_dbus_send_message(sync->conn, reply);
dbus_message_unref(sync->msg);
sync->msg = NULL;
diff --git a/client/transfer.c b/client/transfer.c
index 9e6f0ad..39b0c91 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -51,6 +51,25 @@ struct transfer_callback {
void *data;
};
+struct transfer_data {
+ struct session_data *session;
+ struct transfer_params *params;
+ struct transfer_callback *callback;
+ DBusConnection *conn;
+ char *path; /* Transfer path */
+ gchar *filename; /* Transfer file location */
+ char *name; /* Transfer object name */
+ char *type; /* Transfer object type */
+ int fd;
+ GwObexXfer *xfer;
+ char *buffer;
+ size_t buffer_len;
+ int filled;
+ gint64 size;
+ gint64 transferred;
+ int err;
+};
+
static void append_entry(DBusMessageIter *dict,
const char *key, int type, void *val)
{
@@ -177,12 +196,14 @@ static void transfer_free(struct transfer_data *transfer)
g_free(transfer);
}
-struct transfer_data *transfer_register(struct session_data *session,
+struct transfer_data *transfer_register(DBusConnection *conn,
const char *filename,
const char *name,
const char *type,
- struct transfer_params *params)
+ struct transfer_params *params,
+ void *user_data)
{
+ struct session_data *session = user_data;
struct transfer_data *transfer;
transfer = g_new0(struct transfer_data, 1);
@@ -539,3 +560,50 @@ void transfer_abort(struct transfer_data *transfer)
callback->func(transfer, transfer->transferred, -ECANCELED,
callback->data);
}
+
+int transfer_get_params(struct transfer_data *transfer,
+ struct transfer_params *params)
+{
+ if (!transfer->xfer)
+ return -ENOTCONN;
+
+ params->data = gw_obex_xfer_object_apparam(transfer->xfer,
+ ¶ms->size);
+
+ return 0;
+}
+
+void transfer_clear_buffer(struct transfer_data *transfer)
+{
+ transfer->filled = 0;
+}
+
+const char *transfer_get_buffer(struct transfer_data *transfer, int *size)
+{
+ if (size)
+ *size = transfer->filled;
+
+ return transfer->buffer;
+}
+
+void transfer_set_buffer(struct transfer_data *transfer, char *buffer)
+{
+ transfer->size = strlen(buffer);
+ transfer->buffer = buffer;
+}
+
+void transfer_set_name(struct transfer_data *transfer, const char *name)
+{
+ g_free(transfer->name);
+ transfer->name = g_strdup(name);
+}
+
+const char *transfer_get_path(struct transfer_data *transfer)
+{
+ return transfer->path;
+}
+
+gint64 transfer_get_size(struct transfer_data *transfer)
+{
+ return transfer->size;
+}
diff --git a/client/transfer.h b/client/transfer.h
index 7392267..ac14623 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -25,39 +25,22 @@
struct transfer_params {
guint8 *data;
- gint size;
+ size_t size;
};
struct transfer_callback;
-
-struct transfer_data {
- struct session_data *session;
- struct transfer_params *params;
- struct transfer_callback *callback;
- DBusConnection *conn;
- char *path; /* Transfer path */
- gchar *filename; /* Transfer file location */
- char *name; /* Transfer object name */
- char *type; /* Transfer object type */
- int fd;
- GwObexXfer *xfer;
- char *buffer;
- size_t buffer_len;
- int filled;
- gint64 size;
- gint64 transferred;
- int err;
-};
+struct transfer_data;
typedef void (*transfer_callback_t) (struct transfer_data *transfer,
gint64 transferred, gint err,
void *user_data);
-struct transfer_data *transfer_register(struct session_data *session,
+struct transfer_data *transfer_register(DBusConnection *conn,
const char *filename,
const char *name,
const char *type,
- struct transfer_params *params);
+ struct transfer_params *params,
+ void *user_data);
void transfer_unregister(struct transfer_data *transfer);
@@ -66,3 +49,13 @@ int transfer_get(struct transfer_data *transfer, transfer_callback_t func,
int transfer_put(struct transfer_data *transfer, transfer_callback_t func,
void *user_data);
void transfer_abort(struct transfer_data *transfer);
+
+int transfer_get_params(struct transfer_data *transfer,
+ struct transfer_params *params);
+const char *transfer_get_buffer(struct transfer_data *transfer, int *size);
+void transfer_set_buffer(struct transfer_data *transfer, char *buffer);
+void transfer_clear_buffer(struct transfer_data *transfer);
+
+void transfer_set_name(struct transfer_data *transfer, const char *name);
+const char *transfer_get_path(struct transfer_data *transfer);
+gint64 transfer_get_size(struct transfer_data *transfer);
--
1.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH obexd 4/6] client: separate ftp code from session
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 2/6] client: make session structure private Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 3/6] client: make transfer " Luiz Augusto von Dentz
@ 2011-07-18 10:35 ` Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 5/6] client: separate agent " Luiz Augusto von Dentz
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:35 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This should improve modularization of code
---
Makefile.am | 2 +
client/ftp.c | 382 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/ftp.h | 29 ++++
client/session.c | 323 +---------------------------------------------
4 files changed, 417 insertions(+), 319 deletions(-)
create mode 100644 client/ftp.c
create mode 100644 client/ftp.h
diff --git a/Makefile.am b/Makefile.am
index 049fc10..ab73539 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -128,8 +128,10 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
client/session.h client/session.c \
client/pbap.h client/pbap.c \
client/sync.h client/sync.c \
+ client/ftp.h client/ftp.c \
client/transfer.h client/transfer.c
+
client_obex_client_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @OPENOBEX_LIBS@ @BLUEZ_LIBS@
endif
diff --git a/client/ftp.c b/client/ftp.c
new file mode 100644
index 0000000..d8557f2
--- /dev/null
+++ b/client/ftp.c
@@ -0,0 +1,382 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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 "session.h"
+#include "transfer.h"
+#include "ftp.h"
+
+#define FTP_INTERFACE "org.openobex.FileTransfer"
+
+struct ftp_data {
+ struct session_data *session;
+ DBusConnection *conn;
+ DBusMessage *msg;
+};
+
+static DBusMessage *change_folder(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct session_data *session = ftp->session;
+ GwObex *obex = session_get_obex(session);
+ const char *folder;
+ int err;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &folder,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ if (gw_obex_chdir(obex, folder, &err) == FALSE) {
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "%s", OBEX_ResponseToString(err));
+ }
+
+ return dbus_message_new_method_return(message);
+}
+
+static void append_variant(DBusMessageIter *iter, int type, void *val)
+{
+ DBusMessageIter value;
+ char sig[2] = { type, '\0' };
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
+
+ dbus_message_iter_append_basic(&value, type, val);
+
+ dbus_message_iter_close_container(iter, &value);
+}
+
+static void dict_append_entry(DBusMessageIter *dict,
+ const char *key, int type, void *val)
+{
+ DBusMessageIter entry;
+
+ if (type == DBUS_TYPE_STRING) {
+ const char *str = *((const char **) val);
+ if (str == NULL)
+ return;
+ }
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ append_variant(&entry, type, val);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+static void xml_element(GMarkupParseContext *ctxt,
+ const gchar *element,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **gerr)
+{
+ DBusMessageIter dict, *iter = user_data;
+ gchar *key;
+ gint i;
+
+ if (strcasecmp("folder", element) != 0 && strcasecmp("file", element) != 0)
+ return;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &element);
+
+ /* FIXME: User, Group, Other permission must be reviewed */
+
+ i = 0;
+ for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) {
+ key[0] = g_ascii_toupper(key[0]);
+ if (g_str_equal("Size", key) == TRUE) {
+ guint64 size;
+ size = g_ascii_strtoll(values[i], NULL, 10);
+ dict_append_entry(&dict, key, DBUS_TYPE_UINT64, &size);
+ } else
+ dict_append_entry(&dict, key, DBUS_TYPE_STRING, &values[i]);
+ }
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static const GMarkupParser parser = {
+ xml_element,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static void get_file_callback(struct session_data *session, GError *err,
+ void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ DBusMessage *reply;
+
+ if (!ftp->msg)
+ return;
+
+ if (err)
+ reply = g_dbus_create_error(ftp->msg,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ else
+ reply = dbus_message_new_method_return(ftp->msg);
+
+ g_dbus_send_message(ftp->conn, reply);
+
+ dbus_message_unref(ftp->msg);
+ ftp->msg = NULL;
+}
+
+static void list_folder_callback(struct session_data *session,
+ GError *err, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct transfer_data *transfer = session_get_transfer(session);
+ GMarkupParseContext *ctxt;
+ DBusMessage *reply;
+ DBusMessageIter iter, array;
+ const char *buf;
+ int size;
+
+ reply = dbus_message_new_method_return(ftp->msg);
+
+ buf = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ goto done;
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
+ ctxt = g_markup_parse_context_new(&parser, 0, &array, NULL);
+ g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
+ g_markup_parse_context_free(ctxt);
+ dbus_message_iter_close_container(&iter, &array);
+
+ transfer_clear_buffer(transfer);
+
+done:
+ g_dbus_send_message(ftp->conn, reply);
+ dbus_message_unref(ftp->msg);
+ ftp->msg = NULL;
+}
+
+static DBusMessage *create_folder(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct session_data *session = ftp->session;
+ GwObex *obex = session_get_obex(session);
+ const char *folder;
+ int err;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &folder,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ if (gw_obex_mkdir(obex, folder, &err) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "%s", OBEX_ResponseToString(err));
+
+ return dbus_message_new_method_return(message);
+}
+
+static DBusMessage *list_folder(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct session_data *session = ftp->session;
+
+ if (ftp->msg)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InProgress",
+ "Transfer in progress");
+
+ if (session_get(session, "x-obex/folder-listing",
+ NULL, NULL, NULL, 0, list_folder_callback, ftp) < 0)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "Failed");
+
+ ftp->msg = dbus_message_ref(message);
+
+ return NULL;
+}
+
+static DBusMessage *get_file(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct session_data *session = ftp->session;
+ const char *target_file, *source_file;
+
+ if (ftp->msg)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InProgress",
+ "Transfer in progress");
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &target_file,
+ DBUS_TYPE_STRING, &source_file,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ if (session_get(session, NULL, source_file,
+ target_file, NULL, 0, get_file_callback, NULL) < 0)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "Failed");
+
+ ftp->msg = dbus_message_ref(message);
+
+ return NULL;
+}
+
+static DBusMessage *put_file(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct session_data *session = ftp->session;
+ gchar *sourcefile, *targetfile;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &sourcefile,
+ DBUS_TYPE_STRING, &targetfile,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments",
+ "Invalid arguments in method call");
+
+ if (session_send(session, sourcefile, targetfile) < 0)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "Failed");
+
+ return dbus_message_new_method_return(message);
+}
+
+static DBusMessage *copy_file(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return dbus_message_new_method_return(message);
+}
+
+static DBusMessage *move_file(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return dbus_message_new_method_return(message);
+}
+
+static DBusMessage *delete(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct ftp_data *ftp = user_data;
+ struct session_data *session = ftp->session;
+ GwObex *obex = session_get_obex(session);
+ const char *file;
+ int err;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &file,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ if (gw_obex_delete(obex, file, &err) == FALSE) {
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "%s", OBEX_ResponseToString(err));
+ }
+
+ return dbus_message_new_method_return(message);
+}
+
+static GDBusMethodTable ftp_methods[] = {
+ { "ChangeFolder", "s", "", change_folder },
+ { "CreateFolder", "s", "", create_folder },
+ { "ListFolder", "", "aa{sv}", list_folder,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetFile", "ss", "", get_file,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "PutFile", "ss", "", put_file },
+ { "CopyFile", "ss", "", copy_file },
+ { "MoveFile", "ss", "", move_file },
+ { "Delete", "s", "", delete },
+ { }
+};
+
+static void ftp_free(void *data)
+{
+ struct ftp_data *ftp = data;
+
+ session_unref(ftp->session);
+ dbus_connection_unref(ftp->conn);
+ g_free(ftp);
+}
+
+gboolean ftp_register_interface(DBusConnection *connection, const char *path,
+ void *user_data)
+{
+ struct session_data *session = user_data;
+ struct ftp_data *ftp;
+
+ ftp = g_try_new0(struct ftp_data, 1);
+ if (!ftp)
+ return FALSE;
+
+ ftp->session = session_ref(session);
+ ftp->conn = dbus_connection_ref(connection);
+
+ if (!g_dbus_register_interface(connection, path, FTP_INTERFACE,
+ ftp_methods, NULL, NULL, ftp, ftp_free)) {
+ ftp_free(ftp);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void ftp_unregister_interface(DBusConnection *connection, const char *path)
+{
+ g_dbus_unregister_interface(connection, path, FTP_INTERFACE);
+}
diff --git a/client/ftp.h b/client/ftp.h
new file mode 100644
index 0000000..1af2a3d
--- /dev/null
+++ b/client/ftp.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2007-2010 Intel Corporation
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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
+ *
+ */
+
+#include <gdbus.h>
+
+gboolean ftp_register_interface(DBusConnection *connection, const char *path,
+ void *user_data);
+void ftp_unregister_interface(DBusConnection *connection, const char *path);
diff --git a/client/session.c b/client/session.c
index 8ad9a49..f2168b4 100644
--- a/client/session.c
+++ b/client/session.c
@@ -43,6 +43,7 @@
#include "log.h"
#include "pbap.h"
#include "sync.h"
+#include "ftp.h"
#include "transfer.h"
#include "session.h"
#include "btio.h"
@@ -52,8 +53,6 @@
#define SESSION_INTERFACE "org.openobex.Session"
#define SESSION_BASEPATH "/org/openobex"
-#define FTP_INTERFACE "org.openobex.FileTransfer"
-
#define OBEX_IO_ERROR obex_io_error_quark()
#define BT_BUS_NAME "org.bluez"
@@ -193,8 +192,7 @@ static void session_unregistered(struct session_data *session)
switch (session->uuid.value.uuid16) {
case OBEX_FILETRANS_SVCLASS_ID:
- g_dbus_unregister_interface(session->conn, session->path,
- FTP_INTERFACE);
+ ftp_unregister_interface(session->conn, session->path);
break;
case PBAP_PSE_SVCLASS_ID:
pbap_unregister_interface(session->conn, session->path);
@@ -1034,131 +1032,6 @@ static GDBusMethodTable session_methods[] = {
{ }
};
-static void append_variant(DBusMessageIter *iter, int type, void *val)
-{
- DBusMessageIter value;
- char sig[2] = { type, '\0' };
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
-
- dbus_message_iter_append_basic(&value, type, val);
-
- dbus_message_iter_close_container(iter, &value);
-}
-
-static void dict_append_entry(DBusMessageIter *dict,
- const char *key, int type, void *val)
-{
- DBusMessageIter entry;
-
- if (type == DBUS_TYPE_STRING) {
- const char *str = *((const char **) val);
- if (str == NULL)
- return;
- }
-
- dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
-
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
-
- append_variant(&entry, type, val);
-
- dbus_message_iter_close_container(dict, &entry);
-}
-
-static void xml_element(GMarkupParseContext *ctxt,
- const gchar *element,
- const gchar **names,
- const gchar **values,
- gpointer user_data,
- GError **gerr)
-{
- DBusMessageIter dict, *iter = user_data;
- gchar *key;
- gint i;
-
- if (strcasecmp("folder", element) != 0 && strcasecmp("file", element) != 0)
- return;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
- dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &element);
-
- /* FIXME: User, Group, Other permission must be reviewed */
-
- i = 0;
- for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) {
- key[0] = g_ascii_toupper(key[0]);
- if (g_str_equal("Size", key) == TRUE) {
- guint64 size;
- size = g_ascii_strtoll(values[i], NULL, 10);
- dict_append_entry(&dict, key, DBUS_TYPE_UINT64, &size);
- } else
- dict_append_entry(&dict, key, DBUS_TYPE_STRING, &values[i]);
- }
-
- dbus_message_iter_close_container(iter, &dict);
-}
-
-static const GMarkupParser parser = {
- xml_element,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static void list_folder_callback(struct session_data *session,
- GError *err, void *user_data)
-{
- struct transfer_data *transfer = session->pending->data;
- GMarkupParseContext *ctxt;
- DBusMessage *reply;
- DBusMessageIter iter, array;
- const char *buf;
- int size;
-
- if (err != NULL) {
- reply = g_dbus_create_error(session->msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- goto done;
- } else
- reply = dbus_message_new_method_return(session->msg);
-
- buf = transfer_get_buffer(transfer, &size);
- if (size == 0)
- buf = "";
-
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
- ctxt = g_markup_parse_context_new(&parser, 0, &array, NULL);
- g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
- g_markup_parse_context_free(ctxt);
- dbus_message_iter_close_container(&iter, &array);
-
- transfer_clear_buffer(transfer);
-
-done:
- g_dbus_send_message(session->conn, reply);
- dbus_message_unref(session->msg);
- session->msg = NULL;
-}
-
-static void get_file_callback(struct session_data *session, GError *err,
- void *user_data)
-{
-
-}
-
static void session_request_reply(DBusPendingCall *call, gpointer user_data)
{
struct session_data *session = user_data;
@@ -1321,18 +1194,6 @@ static void session_notify_error(struct session_data *session,
DBusMessage *message;
const char *path;
- if (session->msg) {
- DBusMessage *reply;
-
- reply = g_dbus_create_error(session->msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(session->conn, reply);
-
- dbus_message_unref(session->msg);
- session->msg = NULL;
- }
-
path = transfer_get_path(transfer);
if (agent == NULL || path == NULL)
goto done;
@@ -1365,18 +1226,6 @@ static void session_notify_progress(struct session_data *session,
DBusMessage *message;
const char *path;
- /* For GetFile reply on the first received stream */
- if (session->msg &&
- dbus_message_has_member(session->msg, "GetFile")) {
- DBusMessage *reply;
-
- reply = dbus_message_new_method_return(session->msg);
- g_dbus_send_message(session->conn, reply);
-
- dbus_message_unref(session->msg);
- session->msg = NULL;
- }
-
path = transfer_get_path(transfer);
if (agent == NULL || path == NULL)
goto done;
@@ -1486,169 +1335,6 @@ int session_get(struct session_data *session, const char *type,
return 0;
}
-static DBusMessage *change_folder(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session = user_data;
- const char *folder;
- int err;
-
- if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &folder,
- DBUS_TYPE_INVALID) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- if (gw_obex_chdir(session->obex, folder, &err) == FALSE) {
- return g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "%s", OBEX_ResponseToString(err));
- }
-
- return dbus_message_new_method_return(message);
-}
-
-static DBusMessage *create_folder(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session = user_data;
- const char *folder;
- int err;
-
- if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &folder,
- DBUS_TYPE_INVALID) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- if (gw_obex_mkdir(session->obex, folder, &err) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "%s", OBEX_ResponseToString(err));
-
- return dbus_message_new_method_return(message);
-}
-
-static DBusMessage *list_folder(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session = user_data;
-
- if (session->msg)
- return g_dbus_create_error(message,
- "org.openobex.Error.InProgress",
- "Transfer in progress");
-
- if (session_get(session, "x-obex/folder-listing",
- NULL, NULL, NULL, 0, list_folder_callback, NULL) < 0)
- return g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "Failed");
-
- session->msg = dbus_message_ref(message);
-
- return NULL;
-}
-
-static DBusMessage *get_file(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session = user_data;
- const char *target_file, *source_file;
-
- if (session->msg)
- return g_dbus_create_error(message,
- "org.openobex.Error.InProgress",
- "Transfer in progress");
-
- if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &target_file,
- DBUS_TYPE_STRING, &source_file,
- DBUS_TYPE_INVALID) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- if (session_get(session, NULL, source_file,
- target_file, NULL, 0, get_file_callback, NULL) < 0)
- return g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "Failed");
-
- session->msg = dbus_message_ref(message);
-
- return NULL;
-}
-
-static DBusMessage *put_file(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session = user_data;
- gchar *sourcefile, *targetfile;
-
- if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &sourcefile,
- DBUS_TYPE_STRING, &targetfile,
- DBUS_TYPE_INVALID) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments",
- "Invalid arguments in method call");
-
- if (session_send(session, sourcefile, targetfile) < 0)
- return g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "Failed");
-
- return dbus_message_new_method_return(message);
-}
-
-static DBusMessage *copy_file(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- return dbus_message_new_method_return(message);
-}
-
-static DBusMessage *move_file(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- return dbus_message_new_method_return(message);
-}
-
-static DBusMessage *delete(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session = user_data;
- const char *file;
- int err;
-
- if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &file,
- DBUS_TYPE_INVALID) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- if (gw_obex_delete(session->obex, file, &err) == FALSE) {
- return g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "%s", OBEX_ResponseToString(err));
- }
-
- return dbus_message_new_method_return(message);
-}
-
-static GDBusMethodTable ftp_methods[] = {
- { "ChangeFolder", "s", "", change_folder },
- { "CreateFolder", "s", "", create_folder },
- { "ListFolder", "", "aa{sv}", list_folder,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "GetFile", "ss", "", get_file,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "PutFile", "ss", "", put_file },
- { "CopyFile", "ss", "", copy_file },
- { "MoveFile", "ss", "", move_file },
- { "Delete", "s", "", delete },
- { }
-};
-
int session_send(struct session_data *session, const char *filename,
const char *targetname)
{
@@ -1729,9 +1415,8 @@ const char *session_register(struct session_data *session,
switch (session->uuid.value.uuid16) {
case OBEX_FILETRANS_SVCLASS_ID:
- result = g_dbus_register_interface(session->conn,
- session->path, FTP_INTERFACE,
- ftp_methods, NULL, NULL, session, NULL);
+ result = ftp_register_interface(session->conn, session->path,
+ session);
break;
case PBAP_PSE_SVCLASS_ID:
result = pbap_register_interface(session->conn, session->path,
--
1.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH obexd 5/6] client: separate agent code from session
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
` (2 preceding siblings ...)
2011-07-18 10:35 ` [PATCH obexd 4/6] client: separate ftp code from session Luiz Augusto von Dentz
@ 2011-07-18 10:35 ` Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 6/6] client: separate manager interface code from main Luiz Augusto von Dentz
2011-07-18 10:39 ` [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Marcel Holtmann
5 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:35 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This should improve modularization of code
---
Makefile.am | 3 +-
client/agent.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/agent.h | 43 +++++++++
client/session.c | 174 +++++++-------------------------------
4 files changed, 327 insertions(+), 144 deletions(-)
create mode 100644 client/agent.c
create mode 100644 client/agent.h
diff --git a/Makefile.am b/Makefile.am
index ab73539..8b80da3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -129,7 +129,8 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
client/pbap.h client/pbap.c \
client/sync.h client/sync.c \
client/ftp.h client/ftp.c \
- client/transfer.h client/transfer.c
+ client/transfer.h client/transfer.c \
+ client/agent.h client/agent.c
client_obex_client_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @OPENOBEX_LIBS@ @BLUEZ_LIBS@
diff --git a/client/agent.c b/client/agent.c
new file mode 100644
index 0000000..fe2f35d
--- /dev/null
+++ b/client/agent.c
@@ -0,0 +1,251 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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 <errno.h>
+
+#include "log.h"
+#include "agent.h"
+
+#define AGENT_INTERFACE "org.openobex.Agent"
+
+struct pending_request {
+ DBusPendingCall *call;
+ DBusPendingCallNotifyFunction function;
+ void *data;
+ DBusFreeFunction destroy;
+};
+
+struct agent_data {
+ DBusConnection *conn;
+ char *name;
+ char *path;
+ guint watch;
+ GFunc destroy;
+ void *data;
+ struct pending_request *pending;
+};
+
+static void pending_request_free(struct pending_request *req)
+{
+ if (req->call)
+ dbus_pending_call_unref(req->call);
+
+ if (req->destroy)
+ req->destroy(req->data);
+
+ g_free(req);
+}
+
+void agent_free(struct agent_data *agent)
+{
+ if (agent->watch)
+ g_dbus_remove_watch(agent->conn, agent->watch);
+
+ if (agent->pending) {
+ if (agent->pending->call)
+ dbus_pending_call_cancel(agent->pending->call);
+ pending_request_free(agent->pending);
+ }
+
+ dbus_connection_unref(agent->conn);
+ g_free(agent->name);
+ g_free(agent->path);
+ g_free(agent);
+}
+
+static void agent_disconnected(DBusConnection *connection, void *user_data)
+{
+ struct agent_data *agent = user_data;
+
+ agent->watch = 0;
+
+ if (agent->destroy)
+ agent->destroy(agent, agent->data);
+
+ agent_free(agent);
+}
+
+struct agent_data *agent_create(DBusConnection *conn, const char *name,
+ const char *path, GFunc destroy,
+ void *user_data)
+{
+ struct agent_data *agent;
+
+ agent = g_new0(struct agent_data, 1);
+ agent->conn = dbus_connection_ref(conn);
+ agent->name = g_strdup(name);
+ agent->path = g_strdup(path);
+ agent->destroy = destroy;
+ agent->data = user_data;
+
+ agent->watch = g_dbus_add_disconnect_watch(conn, name,
+ agent_disconnected,
+ agent, NULL);
+
+ return agent;
+}
+
+static void agent_request_reply(DBusPendingCall *call, void *user_data)
+{
+ struct agent_data *agent = user_data;
+ struct pending_request *req = agent->pending;
+
+ if (req->function)
+ req->function(call, req->data);
+
+ pending_request_free(req);
+ agent->pending = NULL;
+}
+
+int agent_request(struct agent_data *agent, const char *path,
+ DBusPendingCallNotifyFunction function,
+ void *user_data, DBusFreeFunction destroy)
+{
+ struct pending_request *req;
+ DBusMessage *message;
+
+ if (agent->pending)
+ return -EBUSY;
+
+ DBG("%s", path);
+
+ message = dbus_message_new_method_call(agent->name,
+ agent->path, AGENT_INTERFACE, "Request");
+
+ dbus_message_append_args(message,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ req = g_new0(struct pending_request, 1);
+ req->function = function;
+ req->destroy = destroy;
+ req->data = user_data;
+
+ if (!dbus_connection_send_with_reply(agent->conn, message,
+ &req->call, -1)) {
+ g_free(req);
+ dbus_message_unref(message);
+ return -ENOMEM;
+ }
+
+ agent->pending = req;
+
+ dbus_message_unref(message);
+
+ dbus_pending_call_set_notify(req->call, agent_request_reply,
+ agent, NULL);
+
+ return 0;
+}
+
+void agent_notify_progress(struct agent_data *agent, const char *path,
+ guint64 transferred)
+{
+ DBusMessage *message;
+
+ DBG("%s", path);
+
+ message = dbus_message_new_method_call(agent->name,
+ agent->path, AGENT_INTERFACE, "Progress");
+ if (message == NULL)
+ return;
+
+ dbus_message_set_no_reply(message, TRUE);
+
+ dbus_message_append_args(message,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_UINT64, &transferred,
+ DBUS_TYPE_INVALID);
+
+ g_dbus_send_message(agent->conn, message);
+}
+
+void agent_notify_complete(struct agent_data *agent, const char *path)
+{
+ DBusMessage *message;
+
+ DBG("%s", path);
+
+ message = dbus_message_new_method_call(agent->name,
+ agent->path, AGENT_INTERFACE, "Complete");
+ if (message == NULL)
+ return;
+
+ dbus_message_set_no_reply(message, TRUE);
+
+ dbus_message_append_args(message,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ g_dbus_send_message(agent->conn, message);
+}
+
+void agent_notify_error(struct agent_data *agent, const char *path,
+ const char *err)
+{
+ DBusMessage *message;
+
+ DBG("%s", path);
+
+ message = dbus_message_new_method_call(agent->name,
+ agent->path, AGENT_INTERFACE, "Error");
+ if (message == NULL)
+ return;
+
+ dbus_message_set_no_reply(message, TRUE);
+
+ dbus_message_append_args(message,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_STRING, &err,
+ DBUS_TYPE_INVALID);
+
+ g_dbus_send_message(agent->conn, message);
+}
+
+void agent_release(struct agent_data *agent)
+{
+ DBusMessage *message;
+
+ DBG("");
+
+ message = dbus_message_new_method_call(agent->name,
+ agent->path, AGENT_INTERFACE, "Release");
+
+ dbus_message_set_no_reply(message, TRUE);
+
+ g_dbus_send_message(agent->conn, message);
+}
+
+const char *agent_get_name(struct agent_data *agent)
+{
+ return agent->name;
+}
+
+const char *agent_get_path(struct agent_data *agent)
+{
+ return agent->path;
+}
diff --git a/client/agent.h b/client/agent.h
new file mode 100644
index 0000000..6fc3ffd
--- /dev/null
+++ b/client/agent.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2007-2010 Intel Corporation
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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
+ *
+ */
+
+#include <gdbus.h>
+
+struct agent_data;
+
+struct agent_data *agent_create(DBusConnection *conn, const char *name,
+ const char *path, GFunc destroy,
+ void *user_data);
+void agent_free(struct agent_data *agent);
+const char *agent_get_name(struct agent_data *agent);
+const char *agent_get_path(struct agent_data *agent);
+int agent_request(struct agent_data *agent, const char *path,
+ DBusPendingCallNotifyFunction function,
+ void *user_data, DBusFreeFunction destroy);
+void agent_notify_progress(struct agent_data *agent, const char *path,
+ guint64 transferred);
+void agent_notify_complete(struct agent_data *agent, const char *path);
+void agent_notify_error(struct agent_data *agent, const char *path,
+ const char *err);
+void agent_release(struct agent_data *agent);
diff --git a/client/session.c b/client/session.c
index f2168b4..a89c760 100644
--- a/client/session.c
+++ b/client/session.c
@@ -47,8 +47,7 @@
#include "transfer.h"
#include "session.h"
#include "btio.h"
-
-#define AGENT_INTERFACE "org.openobex.Agent"
+#include "agent.h"
#define SESSION_INTERFACE "org.openobex.Session"
#define SESSION_BASEPATH "/org/openobex"
@@ -79,19 +78,11 @@ struct session_callback {
};
struct pending_data {
- DBusPendingCall *call;
session_callback_t cb;
struct session_data *session;
struct transfer_data *transfer;
};
-struct agent_data {
- char *name;
- char *path;
- guint watch;
- struct pending_data *pending;
-};
-
struct pending_req {
DBusPendingCall *call;
void *user_data;
@@ -144,48 +135,6 @@ struct session_data *session_ref(struct session_data *session)
return session;
}
-static void free_pending(struct pending_data *pending)
-{
- if (pending->call)
- dbus_pending_call_unref(pending->call);
-
- g_free(pending);
-}
-
-static void agent_free(struct session_data *session)
-{
- struct agent_data *agent = session->agent;
-
- if (agent->watch)
- g_dbus_remove_watch(session->conn, agent->watch);
-
- if (agent->pending) {
- dbus_pending_call_cancel(agent->pending->call);
- free_pending(agent->pending);
- }
-
- session->agent = NULL;
-
- g_free(agent->name);
- g_free(agent->path);
- g_free(agent);
-}
-
-static void agent_release(struct session_data *session)
-{
- struct agent_data *agent = session->agent;
- DBusMessage *message;
-
- message = dbus_message_new_method_call(agent->name,
- agent->path, AGENT_INTERFACE, "Release");
-
- dbus_message_set_no_reply(message, TRUE);
-
- g_dbus_send_message(session->conn, message);
-
- agent_free(session);
-}
-
static void session_unregistered(struct session_data *session)
{
char *path;
@@ -250,8 +199,10 @@ static void session_free(struct session_data *session)
pending_req_finalize(req);
}
- if (session->agent)
- agent_release(session);
+ if (session->agent) {
+ agent_release(session->agent);
+ agent_free(session->agent);
+ }
if (session->watch)
g_dbus_remove_watch(session->conn, session->watch);
@@ -898,15 +849,6 @@ void session_shutdown(struct session_data *session)
session_unref(session);
}
-static void agent_disconnected(DBusConnection *connection, void *user_data)
-{
- struct session_data *session = user_data;
-
- session->agent->watch = 0;
-
- agent_free(session);
-}
-
static DBusMessage *assign_agent(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
@@ -947,13 +889,14 @@ static DBusMessage *release_agent(DBusConnection *connection,
sender = dbus_message_get_sender(message);
- if (agent == NULL || g_str_equal(sender, agent->name) == FALSE ||
- g_str_equal(path, agent->path) == FALSE)
+ if (agent == NULL ||
+ g_str_equal(sender, agent_get_name(agent)) == FALSE ||
+ g_str_equal(path, agent_get_path(agent)) == FALSE)
return g_dbus_create_error(message,
"org.openobex.Error.NotAuthorized",
"Not Authorized");
- agent_free(session);
+ agent_free(agent);
return dbus_message_new_method_return(message);
}
@@ -1034,9 +977,8 @@ static GDBusMethodTable session_methods[] = {
static void session_request_reply(DBusPendingCall *call, gpointer user_data)
{
- struct session_data *session = user_data;
- struct agent_data *agent = session->agent;
- struct pending_data *pending = agent->pending;
+ struct pending_data *pending = user_data;
+ struct session_data *session = pending->session;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
const char *name;
DBusError derr;
@@ -1067,11 +1009,8 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
if (strlen(name))
transfer_set_name(pending->transfer, name);
- agent->pending = NULL;
-
pending->cb(session, NULL, pending->transfer);
dbus_message_unref(reply);
- free_pending(pending);
return;
}
@@ -1082,7 +1021,7 @@ static gboolean session_request_proceed(gpointer data)
struct transfer_data *transfer = pending->transfer;
pending->cb(pending->session, NULL, transfer);
- free_pending(pending);
+ g_free(pending);
return FALSE;
}
@@ -1091,9 +1030,9 @@ static int session_request(struct session_data *session, session_callback_t cb,
struct transfer_data *transfer)
{
struct agent_data *agent = session->agent;
- DBusMessage *message;
struct pending_data *pending;
const char *path;
+ int err;
pending = g_new0(struct pending_data, 1);
pending->cb = cb;
@@ -1107,28 +1046,13 @@ static int session_request(struct session_data *session, session_callback_t cb,
return 0;
}
- message = dbus_message_new_method_call(agent->name,
- agent->path, AGENT_INTERFACE, "Request");
-
- dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
-
- if (!dbus_connection_send_with_reply(session->conn, message,
- &pending->call, -1)) {
- dbus_message_unref(message);
- return -ENOMEM;
+ err = agent_request(agent, path, session_request_reply, pending,
+ g_free);
+ if (err < 0) {
+ g_free(pending);
+ return err;
}
- agent->pending = pending;
-
- dbus_message_unref(message);
-
- dbus_pending_call_set_notify(pending->call, session_request_reply,
- session, NULL);
-
- DBG("Agent.Request(\"%s\")", path);
-
return 0;
}
@@ -1158,7 +1082,6 @@ static void session_notify_complete(struct session_data *session,
struct transfer_data *transfer)
{
struct agent_data *agent = session->agent;
- DBusMessage *message;
const char *path;
path = transfer_get_path(transfer);
@@ -1166,18 +1089,7 @@ static void session_notify_complete(struct session_data *session,
if (agent == NULL || path == NULL)
goto done;
- message = dbus_message_new_method_call(agent->name,
- agent->path, AGENT_INTERFACE, "Complete");
- if (message == NULL)
- return;
-
- dbus_message_set_no_reply(message, TRUE);
-
- dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
-
- g_dbus_send_message(session->conn, message);
+ agent_notify_complete(agent, path);
done:
@@ -1191,26 +1103,13 @@ static void session_notify_error(struct session_data *session,
GError *err)
{
struct agent_data *agent = session->agent;
- DBusMessage *message;
const char *path;
path = transfer_get_path(transfer);
if (agent == NULL || path == NULL)
goto done;
- message = dbus_message_new_method_call(agent->name,
- agent->path, AGENT_INTERFACE, "Error");
- if (message == NULL)
- return;
-
- dbus_message_set_no_reply(message, TRUE);
-
- dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_STRING, &err->message,
- DBUS_TYPE_INVALID);
-
- g_dbus_send_message(session->conn, message);
+ agent_notify_error(agent, path, err->message);
done:
error("Transfer(%p) Error: %s", transfer, err->message);
@@ -1223,26 +1122,13 @@ static void session_notify_progress(struct session_data *session,
gint64 transferred)
{
struct agent_data *agent = session->agent;
- DBusMessage *message;
const char *path;
path = transfer_get_path(transfer);
if (agent == NULL || path == NULL)
goto done;
- message = dbus_message_new_method_call(agent->name,
- agent->path, AGENT_INTERFACE, "Progress");
- if (message == NULL)
- goto done;
-
- dbus_message_set_no_reply(message, TRUE);
-
- dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_UINT64, &transferred,
- DBUS_TYPE_INVALID);
-
- g_dbus_send_message(session->conn, message);
+ agent_notify_progress(agent, path, transferred);
done:
DBG("Transfer(%p) progress: %ld bytes", transfer,
@@ -1488,6 +1374,13 @@ int session_put(struct session_data *session, char *buf, const char *targetname)
return 0;
}
+static void agent_destroy(gpointer data, gpointer user_data)
+{
+ struct session_data *session = user_data;
+
+ session->agent = NULL;
+}
+
int session_set_agent(struct session_data *session, const char *name,
const char *path)
{
@@ -1499,17 +1392,12 @@ int session_set_agent(struct session_data *session, const char *name,
if (session->agent)
return -EALREADY;
- agent = g_new0(struct agent_data, 1);
- agent->name = g_strdup(name);
- agent->path = g_strdup(path);
+ agent = agent_create(session->conn, name, path, agent_destroy,
+ session);
if (session->watch == 0)
session_set_owner(session, name, owner_disconnected);
- agent->watch = g_dbus_add_disconnect_watch(session->conn, name,
- agent_disconnected,
- session, NULL);
-
session->agent = agent;
return 0;
@@ -1526,7 +1414,7 @@ const char *session_get_agent(struct session_data *session)
if (agent == NULL)
return NULL;
- return agent->name;
+ return agent_get_name(session->agent);
}
const char *session_get_owner(struct session_data *session)
--
1.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH obexd 6/6] client: separate manager interface code from main
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
` (3 preceding siblings ...)
2011-07-18 10:35 ` [PATCH obexd 5/6] client: separate agent " Luiz Augusto von Dentz
@ 2011-07-18 10:35 ` Luiz Augusto von Dentz
2011-07-18 10:39 ` [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Marcel Holtmann
5 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:35 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Move manager interface code to it own file.
---
Makefile.am | 1 +
client/main.c | 540 +-------------------------------------------------
client/manager.c | 589 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/manager.h | 25 +++
4 files changed, 619 insertions(+), 536 deletions(-)
create mode 100644 client/manager.c
create mode 100644 client/manager.h
diff --git a/Makefile.am b/Makefile.am
index 8b80da3..5080ee1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -125,6 +125,7 @@ libexec_PROGRAMS += client/obex-client
client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
$(gwobex_sources) $(btio_sources) \
client/main.c src/log.h src/log.c \
+ client/manager.h client/manager.c \
client/session.h client/session.c \
client/pbap.h client/pbap.c \
client/sync.h client/sync.c \
diff --git a/client/main.c b/client/main.c
index 19ca436..618ad21 100644
--- a/client/main.c
+++ b/client/main.c
@@ -35,521 +35,7 @@
#include <gdbus.h>
#include "log.h"
-#include "transfer.h"
-#include "session.h"
-
-#define CLIENT_SERVICE "org.openobex.client"
-
-#define CLIENT_INTERFACE "org.openobex.Client"
-#define CLIENT_PATH "/"
-
-struct send_data {
- DBusConnection *connection;
- DBusMessage *message;
- gchar *sender;
- gchar *agent;
- char *filename;
- GPtrArray *files;
-};
-
-static GSList *sessions = NULL;
-
-static void shutdown_session(struct session_data *session)
-{
- sessions = g_slist_remove(sessions, session);
- session_shutdown(session);
- session_unref(session);
-}
-
-static void unregister_session(void *data)
-{
- struct session_data *session = data;
-
- if (g_slist_find(sessions, session) == NULL)
- return;
-
- sessions = g_slist_remove(sessions, session);
- session_unref(session);
-}
-
-static void create_callback(struct session_data *session, GError *err,
- void *user_data)
-{
- struct send_data *data = user_data;
- unsigned int i;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- shutdown_session(session);
- goto done;
- }
-
- if (session_get_target(session) != NULL) {
- const char *path;
-
- path = session_register(session, unregister_session);
-
- g_dbus_send_reply(data->connection, data->message,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
- goto done;
- }
-
- g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
-
- session_set_agent(session, data->sender, data->agent);
-
- for (i = 0; i < data->files->len; i++) {
- const gchar *filename = g_ptr_array_index(data->files, i);
- gchar *basename = g_path_get_basename(filename);
-
- if (session_send(session, filename, basename) < 0) {
- g_free(basename);
- break;
- }
-
- g_free(basename);
- }
-
- /* No need to keep a reference for SendFiles */
- sessions = g_slist_remove(sessions, session);
- session_unref(session);
-
-done:
- if (data->files)
- g_ptr_array_free(data->files, TRUE);
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->sender);
- g_free(data->agent);
- g_free(data);
-}
-
-static int parse_device_dict(DBusMessageIter *iter,
- const char **source, const char **dest, const char **target,
- uint8_t *channel)
-{
- while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter entry, value;
- const char *key;
-
- dbus_message_iter_recurse(iter, &entry);
- dbus_message_iter_get_basic(&entry, &key);
-
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &value);
-
- switch (dbus_message_iter_get_arg_type(&value)) {
- case DBUS_TYPE_STRING:
- if (g_str_equal(key, "Source") == TRUE)
- dbus_message_iter_get_basic(&value, source);
- else if (g_str_equal(key, "Destination") == TRUE)
- dbus_message_iter_get_basic(&value, dest);
- else if (g_str_equal(key, "Target") == TRUE)
- dbus_message_iter_get_basic(&value, target);
- break;
- case DBUS_TYPE_BYTE:
- if (g_str_equal(key, "Channel") == TRUE)
- dbus_message_iter_get_basic(&value, channel);
- break;
- }
-
- dbus_message_iter_next(iter);
- }
-
- return 0;
-}
-
-static DBusMessage *send_files(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- DBusMessageIter iter, array;
- struct session_data *session;
- GPtrArray *files;
- struct send_data *data;
- const char *agent, *source = NULL, *dest = NULL, *target = NULL;
- const char *sender;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
-
- parse_device_dict(&array, &source, &dest, &target, &channel);
- if (dest == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &array);
-
- files = g_ptr_array_new();
- if (files == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.NoMemory", NULL);
-
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
- char *value;
-
- dbus_message_iter_get_basic(&array, &value);
- g_ptr_array_add(files, value);
-
- dbus_message_iter_next(&array);
- }
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_get_basic(&iter, &agent);
-
- if (files->len == 0) {
- g_ptr_array_free(files, TRUE);
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
- }
-
- sender = dbus_message_get_sender(message);
-
- data = g_try_malloc0(sizeof(*data));
- if (data == NULL) {
- g_ptr_array_free(files, TRUE);
- 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(sender);
- data->agent = g_strdup(agent);
- data->files = files;
-
- session = session_create(source, dest, "OPP", channel, sender,
- create_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- return NULL;
- }
-
- g_ptr_array_free(data->files, TRUE);
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->sender);
- g_free(data->agent);
- g_free(data);
-
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
-static void pull_complete_callback(struct session_data *session,
- GError *err, void *user_data)
-{
- struct send_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- goto done;
- }
-
- g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
-
-done:
- shutdown_session(session);
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->filename);
- g_free(data->sender);
- g_free(data);
-}
-
-static void pull_session_callback(struct session_data *session,
- GError *err, void *user_data)
-{
- struct send_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- shutdown_session(session);
- goto done;
- }
-
- session_pull(session, "text/x-vcard", data->filename,
- pull_complete_callback, data);
-
- return;
-
-done:
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->filename);
- g_free(data->sender);
- g_free(data);
-}
-
-static DBusMessage *pull_business_card(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- DBusMessageIter iter, dict;
- struct session_data *session;
- struct send_data *data;
- const char *source = NULL, *dest = NULL, *target = NULL;
- const char *name = NULL;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &dict);
-
- parse_device_dict(&dict, &source, &dest, &target, &channel);
- if (dest == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- dbus_message_iter_get_basic(&iter, &name);
-
- 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));
- data->filename = g_strdup(name);
-
- session = session_create(source, dest, "OPP", channel, data->sender,
- pull_session_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- return NULL;
- }
-
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->sender);
- g_free(data->filename);
- g_free(data);
-
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
-static DBusMessage *exchange_business_cards(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
-static struct session_data *find_session(const char *path)
-{
- GSList *l;
-
- for (l = sessions; l; l = l->next) {
- struct session_data *session = l->data;
-
- if (g_str_equal(session_get_path(session), path) == TRUE)
- return session;
- }
-
- return NULL;
-}
-
-static DBusMessage *create_session(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- DBusMessageIter iter, dict;
- struct session_data *session;
- struct send_data *data;
- const char *source = NULL, *dest = NULL, *target = NULL;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &dict);
-
- parse_device_dict(&dict, &source, &dest, &target, &channel);
- if (dest == NULL || target == 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));
-
- session = session_create(source, dest, target, channel, data->sender,
- create_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- 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 DBusMessage *remove_session(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct session_data *session;
- const gchar *sender, *path;
-
- if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- session = find_session(path);
- if (session == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- sender = dbus_message_get_sender(message);
- if (g_str_equal(sender, session_get_owner(session)) == FALSE)
- return g_dbus_create_error(message,
- "org.openobex.Error.NotAuthorized",
- "Not Authorized");
-
- shutdown_session(session);
-
- return dbus_message_new_method_return(message);
-}
-
-static void capabilities_complete_callback(struct session_data *session,
- GError *err, void *user_data)
-{
- struct transfer_data *transfer = session_get_transfer(session);
- struct send_data *data = user_data;
- const char *capabilities;
- int size;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- goto done;
- }
-
- capabilities = transfer_get_buffer(transfer, &size);
- if (size == 0)
- capabilities = "";
-
- g_dbus_send_reply(data->connection, data->message,
- DBUS_TYPE_STRING, &capabilities,
- DBUS_TYPE_INVALID);
-
-done:
-
- shutdown_session(session);
- 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,
- GError *err, void *user_data)
-{
- struct send_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- shutdown_session(session);
- 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 session_data *session;
- struct send_data *data;
- const char *source = NULL, *dest = NULL, *target = NULL;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &dict);
-
- parse_device_dict(&dict, &source, &dest, &target, &channel);
- 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";
-
- session = session_create(source, dest, target, channel, data->sender,
- capability_session_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- 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 },
- { "PullBusinessCard", "a{sv}s", "", pull_business_card,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "ExchangeBusinessCards", "a{sv}ss", "", exchange_business_cards,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "CreateSession", "a{sv}", "o", create_session,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "RemoveSession", "o", "", remove_session,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "GetCapabilities", "a{sv}", "s", get_capabilities,
- G_DBUS_METHOD_FLAG_ASYNC },
- { }
-};
+#include "manager.h"
static GMainLoop *event_loop = NULL;
@@ -585,8 +71,6 @@ int main(int argc, char *argv[])
{
GOptionContext *context;
struct sigaction sa;
- DBusConnection *conn;
- DBusError derr;
GError *gerr = NULL;
context = g_option_context_new(NULL);
@@ -601,24 +85,10 @@ int main(int argc, char *argv[])
g_option_context_free(context);
- dbus_error_init(&derr);
+ event_loop = g_main_loop_new(NULL, FALSE);
- conn = g_dbus_setup_bus(DBUS_BUS_SESSION, CLIENT_SERVICE, &derr);
- if (dbus_error_is_set(&derr) == TRUE) {
- g_printerr("%s: %s\n", derr.name, derr.message);
- dbus_error_free(&derr);
+ if (manager_init() < 0)
exit(EXIT_FAILURE);
- }
-
- if (g_dbus_register_interface(conn, CLIENT_PATH, CLIENT_INTERFACE,
- client_methods, NULL, NULL,
- NULL, NULL) == FALSE) {
- g_printerr("Can't register client interface\n");
- dbus_connection_unref(conn);
- exit(EXIT_FAILURE);
- }
-
- event_loop = g_main_loop_new(NULL, FALSE);
__obex_log_init("obex-client", option_debug, !option_stderr);
@@ -631,9 +101,7 @@ int main(int argc, char *argv[])
g_main_loop_run(event_loop);
- g_dbus_unregister_interface(conn, CLIENT_PATH, CLIENT_INTERFACE);
-
- dbus_connection_unref(conn);
+ manager_exit();
g_main_loop_unref(event_loop);
diff --git a/client/manager.c b/client/manager.c
new file mode 100644
index 0000000..e7eb70d
--- /dev/null
+++ b/client/manager.c
@@ -0,0 +1,589 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <syslog.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "log.h"
+#include "transfer.h"
+#include "session.h"
+#include "manager.h"
+
+#define CLIENT_SERVICE "org.openobex.client"
+
+#define CLIENT_INTERFACE "org.openobex.Client"
+#define CLIENT_PATH "/"
+
+struct send_data {
+ DBusConnection *connection;
+ DBusMessage *message;
+ gchar *sender;
+ gchar *agent;
+ char *filename;
+ GPtrArray *files;
+};
+
+static GSList *sessions = NULL;
+
+static void shutdown_session(struct session_data *session)
+{
+ sessions = g_slist_remove(sessions, session);
+ session_shutdown(session);
+ session_unref(session);
+}
+
+static void unregister_session(void *data)
+{
+ struct session_data *session = data;
+
+ if (g_slist_find(sessions, session) == NULL)
+ return;
+
+ sessions = g_slist_remove(sessions, session);
+ session_unref(session);
+}
+
+static void create_callback(struct session_data *session, GError *err,
+ void *user_data)
+{
+ struct send_data *data = user_data;
+ unsigned int i;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(data->message,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ g_dbus_send_message(data->connection, error);
+ shutdown_session(session);
+ goto done;
+ }
+
+ if (session_get_target(session) != NULL) {
+ const char *path;
+
+ path = session_register(session, unregister_session);
+
+ g_dbus_send_reply(data->connection, data->message,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+ goto done;
+ }
+
+ g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
+
+ session_set_agent(session, data->sender, data->agent);
+
+ for (i = 0; i < data->files->len; i++) {
+ const gchar *filename = g_ptr_array_index(data->files, i);
+ gchar *basename = g_path_get_basename(filename);
+
+ if (session_send(session, filename, basename) < 0) {
+ g_free(basename);
+ break;
+ }
+
+ g_free(basename);
+ }
+
+ /* No need to keep a reference for SendFiles */
+ sessions = g_slist_remove(sessions, session);
+ session_unref(session);
+
+done:
+ if (data->files)
+ g_ptr_array_free(data->files, TRUE);
+ dbus_message_unref(data->message);
+ dbus_connection_unref(data->connection);
+ g_free(data->sender);
+ g_free(data->agent);
+ g_free(data);
+}
+
+static int parse_device_dict(DBusMessageIter *iter,
+ const char **source, const char **dest, const char **target,
+ uint8_t *channel)
+{
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key;
+
+ dbus_message_iter_recurse(iter, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ switch (dbus_message_iter_get_arg_type(&value)) {
+ case DBUS_TYPE_STRING:
+ if (g_str_equal(key, "Source") == TRUE)
+ dbus_message_iter_get_basic(&value, source);
+ else if (g_str_equal(key, "Destination") == TRUE)
+ dbus_message_iter_get_basic(&value, dest);
+ else if (g_str_equal(key, "Target") == TRUE)
+ dbus_message_iter_get_basic(&value, target);
+ break;
+ case DBUS_TYPE_BYTE:
+ if (g_str_equal(key, "Channel") == TRUE)
+ dbus_message_iter_get_basic(&value, channel);
+ break;
+ }
+
+ dbus_message_iter_next(iter);
+ }
+
+ return 0;
+}
+
+static DBusMessage *send_files(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter, array;
+ struct session_data *session;
+ GPtrArray *files;
+ struct send_data *data;
+ const char *agent, *source = NULL, *dest = NULL, *target = NULL;
+ const char *sender;
+ uint8_t channel = 0;
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_recurse(&iter, &array);
+
+ parse_device_dict(&array, &source, &dest, &target, &channel);
+ if (dest == NULL)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &array);
+
+ files = g_ptr_array_new();
+ if (files == NULL)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.NoMemory", NULL);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
+ char *value;
+
+ dbus_message_iter_get_basic(&array, &value);
+ g_ptr_array_add(files, value);
+
+ dbus_message_iter_next(&array);
+ }
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_get_basic(&iter, &agent);
+
+ if (files->len == 0) {
+ g_ptr_array_free(files, TRUE);
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+ }
+
+ sender = dbus_message_get_sender(message);
+
+ data = g_try_malloc0(sizeof(*data));
+ if (data == NULL) {
+ g_ptr_array_free(files, TRUE);
+ 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(sender);
+ data->agent = g_strdup(agent);
+ data->files = files;
+
+ session = session_create(source, dest, "OPP", channel, sender,
+ create_callback, data);
+ if (session != NULL) {
+ sessions = g_slist_append(sessions, session);
+ return NULL;
+ }
+
+ g_ptr_array_free(data->files, TRUE);
+ dbus_message_unref(data->message);
+ dbus_connection_unref(data->connection);
+ g_free(data->sender);
+ g_free(data->agent);
+ g_free(data);
+
+ return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
+}
+
+static void pull_complete_callback(struct session_data *session,
+ GError *err, void *user_data)
+{
+ struct send_data *data = user_data;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(data->message,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ g_dbus_send_message(data->connection, error);
+ goto done;
+ }
+
+ g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
+
+done:
+ shutdown_session(session);
+ dbus_message_unref(data->message);
+ dbus_connection_unref(data->connection);
+ g_free(data->filename);
+ g_free(data->sender);
+ g_free(data);
+}
+
+static void pull_session_callback(struct session_data *session,
+ GError *err, void *user_data)
+{
+ struct send_data *data = user_data;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(data->message,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ g_dbus_send_message(data->connection, error);
+ shutdown_session(session);
+ goto done;
+ }
+
+ session_pull(session, "text/x-vcard", data->filename,
+ pull_complete_callback, data);
+
+ return;
+
+done:
+ dbus_message_unref(data->message);
+ dbus_connection_unref(data->connection);
+ g_free(data->filename);
+ g_free(data->sender);
+ g_free(data);
+}
+
+static DBusMessage *pull_business_card(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter, dict;
+ struct session_data *session;
+ struct send_data *data;
+ const char *source = NULL, *dest = NULL, *target = NULL;
+ const char *name = NULL;
+ uint8_t channel = 0;
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_recurse(&iter, &dict);
+
+ parse_device_dict(&dict, &source, &dest, &target, &channel);
+ if (dest == NULL)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_get_basic(&iter, &name);
+
+ 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));
+ data->filename = g_strdup(name);
+
+ session = session_create(source, dest, "OPP", channel, data->sender,
+ pull_session_callback, data);
+ if (session != NULL) {
+ sessions = g_slist_append(sessions, session);
+ return NULL;
+ }
+
+ dbus_message_unref(data->message);
+ dbus_connection_unref(data->connection);
+ g_free(data->sender);
+ g_free(data->filename);
+ g_free(data);
+
+ return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
+}
+
+static DBusMessage *exchange_business_cards(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
+}
+
+static struct session_data *find_session(const char *path)
+{
+ GSList *l;
+
+ for (l = sessions; l; l = l->next) {
+ struct session_data *session = l->data;
+
+ if (g_str_equal(session_get_path(session), path) == TRUE)
+ return session;
+ }
+
+ return NULL;
+}
+
+static DBusMessage *create_session(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter, dict;
+ struct session_data *session;
+ struct send_data *data;
+ const char *source = NULL, *dest = NULL, *target = NULL;
+ uint8_t channel = 0;
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_recurse(&iter, &dict);
+
+ parse_device_dict(&dict, &source, &dest, &target, &channel);
+ if (dest == NULL || target == 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));
+
+ session = session_create(source, dest, target, channel, data->sender,
+ create_callback, data);
+ if (session != NULL) {
+ sessions = g_slist_append(sessions, session);
+ 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 DBusMessage *remove_session(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct session_data *session;
+ const gchar *sender, *path;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ session = find_session(path);
+ if (session == NULL)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ sender = dbus_message_get_sender(message);
+ if (g_str_equal(sender, session_get_owner(session)) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.NotAuthorized",
+ "Not Authorized");
+
+ shutdown_session(session);
+
+ return dbus_message_new_method_return(message);
+}
+
+static void capabilities_complete_callback(struct session_data *session,
+ GError *err, void *user_data)
+{
+ struct transfer_data *transfer = session_get_transfer(session);
+ struct send_data *data = user_data;
+ const char *capabilities;
+ int size;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(data->message,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ g_dbus_send_message(data->connection, error);
+ goto done;
+ }
+
+ capabilities = transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ capabilities = "";
+
+ g_dbus_send_reply(data->connection, data->message,
+ DBUS_TYPE_STRING, &capabilities,
+ DBUS_TYPE_INVALID);
+
+done:
+
+ shutdown_session(session);
+ 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,
+ GError *err, void *user_data)
+{
+ struct send_data *data = user_data;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(data->message,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ g_dbus_send_message(data->connection, error);
+ shutdown_session(session);
+ 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 session_data *session;
+ struct send_data *data;
+ const char *source = NULL, *dest = NULL, *target = NULL;
+ uint8_t channel = 0;
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_recurse(&iter, &dict);
+
+ parse_device_dict(&dict, &source, &dest, &target, &channel);
+ 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";
+
+ session = session_create(source, dest, target, channel, data->sender,
+ capability_session_callback, data);
+ if (session != NULL) {
+ sessions = g_slist_append(sessions, session);
+ 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 },
+ { "PullBusinessCard", "a{sv}s", "", pull_business_card,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "ExchangeBusinessCards", "a{sv}ss", "", exchange_business_cards,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "CreateSession", "a{sv}", "o", create_session,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "RemoveSession", "o", "", remove_session,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetCapabilities", "a{sv}", "s", get_capabilities,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { }
+};
+
+static DBusConnection *conn = NULL;
+
+int manager_init(void)
+{
+ DBusError derr;
+
+ dbus_error_init(&derr);
+
+ conn = g_dbus_setup_bus(DBUS_BUS_SESSION, CLIENT_SERVICE, &derr);
+ if (dbus_error_is_set(&derr) == TRUE) {
+ g_printerr("%s: %s\n", derr.name, derr.message);
+ dbus_error_free(&derr);
+ return -1;
+ }
+
+ if (g_dbus_register_interface(conn, CLIENT_PATH, CLIENT_INTERFACE,
+ client_methods, NULL, NULL,
+ NULL, NULL) == FALSE) {
+ g_printerr("Can't register client interface\n");
+ dbus_connection_unref(conn);
+ conn = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+void manager_exit(void)
+{
+ if (conn == NULL)
+ return;
+
+ g_dbus_unregister_interface(conn, CLIENT_PATH, CLIENT_INTERFACE);
+ dbus_connection_unref(conn);
+}
diff --git a/client/manager.h b/client/manager.h
new file mode 100644
index 0000000..8756982
--- /dev/null
+++ b/client/manager.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * OBEX Server
+ *
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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
+ *
+ */
+
+int manager_init(void);
+void manager_exit(void);
--
1.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
` (4 preceding siblings ...)
2011-07-18 10:35 ` [PATCH obexd 6/6] client: separate manager interface code from main Luiz Augusto von Dentz
@ 2011-07-18 10:39 ` Marcel Holtmann
2011-07-18 10:54 ` Luiz Augusto von Dentz
5 siblings, 1 reply; 8+ messages in thread
From: Marcel Holtmann @ 2011-07-18 10:39 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hi Luis,
> This avoid having to iterate twice in the list to free its elements.
please make sure we have the same workaround for older GLib versions
without this function. At this point of time, I wanna allow building it
with older GLib versions. We can revisit that at some point in the
future and remove that cruft, but for now it seems reasonable.
Regards
Marcel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated
2011-07-18 10:39 ` [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Marcel Holtmann
@ 2011-07-18 10:54 ` Luiz Augusto von Dentz
0 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2011-07-18 10:54 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
Hi Marcel,
On Mon, Jul 18, 2011 at 1:39 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Luis,
>
>> This avoid having to iterate twice in the list to free its elements.
>
> please make sure we have the same workaround for older GLib versions
> without this function. At this point of time, I wanna allow building it
> with older GLib versions. We can revisit that at some point in the
> future and remove that cruft, but for now it seems reasonable.
Right, Ive forgot about that.. gonna add in v2
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-07-18 10:54 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-18 10:35 [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 2/6] client: make session structure private Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 3/6] client: make transfer " Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 4/6] client: separate ftp code from session Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 5/6] client: separate agent " Luiz Augusto von Dentz
2011-07-18 10:35 ` [PATCH obexd 6/6] client: separate manager interface code from main Luiz Augusto von Dentz
2011-07-18 10:39 ` [PATCH obexd 1/6] Make use of g_slist_free_full when elements are dynamically-allocated Marcel Holtmann
2011-07-18 10:54 ` Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox