From 75d32c6b3a3bddaad19b7880950f9a503afe652b Mon Sep 17 00:00:00 2001 From: Raymond Liu Date: Mon, 15 Dec 2008 13:57:38 +0800 Subject: [PATCH] obexd: Implement Select function for PBAP Client --- obexd/client/pbap.c | 156 ++++++++++++++++++++++++++++++++++------- obexd/client/pbap.h | 7 +- obexd/client/session.c | 2 +- obexd/client/session.h | 1 + 4 files changed, 138 insertions(+), 28 deletions(-) diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c index e29d3c9ee..4a536d6d8 100644 --- a/obexd/client/pbap.c +++ b/obexd/client/pbap.c @@ -32,55 +32,159 @@ #include "session.h" #include "pbap.h" -static DBusMessage *pbap_pull_phonebook(DBusConnection *connection, - DBusMessage *message, void *user_data) +#define ERROR_INF PBAP_INTERFACE ".Error" + +static gchar *build_phonebook_path(const char *location, const char *item) { - return NULL; + gchar *path = NULL, *tmp, *tmp1; + + if (!g_ascii_strcasecmp(location, "INT") || + !g_ascii_strcasecmp(location, "INTERNAL")) + path = g_strdup("telecom"); + else if (!g_ascii_strncasecmp(location, "SIM", 3)) { + if (strlen(location) == 3) + tmp = g_strdup("SIM1"); + else + tmp = g_ascii_strup(location, 4); + + path = g_build_filename(tmp, "telecom", NULL); + g_free(tmp); + } else + return NULL; + + if (!g_ascii_strcasecmp(item, "PB") || + !g_ascii_strcasecmp(item, "ICH") || + !g_ascii_strcasecmp(item, "OCH") || + !g_ascii_strcasecmp(item, "MCH") || + !g_ascii_strcasecmp(item, "CCH")) { + tmp = path; + tmp1 = g_ascii_strdown(item, -1); + path = g_build_filename(tmp, tmp1, NULL); + g_free(tmp); + g_free(tmp1); + } else { + g_free(path); + return NULL; + } + + return path; } -static DBusMessage *pbap_set_phonebook(DBusConnection *connection, - DBusMessage *message, void *user_data) +/* should only be called inside pbap_set_path */ +static void pbap_reset_path(struct session_data *session) { - return NULL; + int err = 0; + char **paths = NULL, **item; + struct pbap_data *pbapdata = session->pbapdata; + + if (!pbapdata->path) + return; + + gw_obex_chdir(session->obex, "", &err); + + paths = g_strsplit(pbapdata->path, "/", 3); + + for (item = paths; *item; item++) + gw_obex_chdir(session->obex, *item, &err); + + g_strfreev(paths); } -static DBusMessage *pbap_pull_vcard_listing(DBusConnection *connection, - DBusMessage *message, void *user_data) +static gint pbap_set_path(struct session_data *session, const char *path) { - return NULL; + int err = 0; + char **paths = NULL, **item; + struct pbap_data *pbapdata = session->pbapdata; + + if (!path) + return OBEX_RSP_BAD_REQUEST; + + if (pbapdata->path != NULL && g_str_equal(pbapdata->path, path)) + return 0; + + if (gw_obex_chdir(session->obex, "", &err) == FALSE) { + if (err == OBEX_RSP_NOT_IMPLEMENTED) + goto done; + goto fail; + } + + paths = g_strsplit(path, "/", 3); + for (item = paths; *item; item++) { + if (gw_obex_chdir(session->obex, *item, &err) == FALSE) { + /* we need to reset the path to the saved one on fail*/ + pbap_reset_path(session); + goto fail; + } + } + + g_strfreev(paths); + +done: + g_free(pbapdata->path); + pbapdata->path = g_strdup(path); + return 0; + +fail: + if (paths) + g_strfreev(paths); + + return err; } -static DBusMessage *pbap_pull_vcard_entry(DBusConnection *connection, - DBusMessage *message, void *user_data) +static DBusMessage *pbap_select(DBusConnection *connection, + DBusMessage *message, void *user_data) { - return NULL; + struct session_data *session = user_data; + const char *item, *location; + char *path = NULL; + int err = 0; + + if (dbus_message_get_args(message, NULL, + DBUS_TYPE_STRING, &location, + DBUS_TYPE_STRING, &item, + DBUS_TYPE_INVALID) == FALSE) + return g_dbus_create_error(message, + ERROR_INF ".InvalidArguments", NULL); + + path = build_phonebook_path(location, item); + if (!path) + return g_dbus_create_error(message, + ERROR_INF ".InvalidArguments", "InvalidPhonebook"); + + err = pbap_set_path(session, path); + g_free(path); + if (err) + return g_dbus_create_error(message, + ERROR_INF ".Failed", + OBEX_ResponseToString(err)); + + return dbus_message_new_method_return(message); } static GDBusMethodTable pbap_methods[] = { - /* PullPhoneBook input parameters : Name, Filter, Format, - MaxListCount, ListStartOffset */ - { "PullPhoneBook", "styqq", "s", pbap_pull_phonebook, - G_DBUS_METHOD_FLAG_ASYNC }, - /* SetPhoneBook input parameters : Name */ - { "SetPhoneBook", "s", "", pbap_set_phonebook }, - /* PullvCardListing input parameters : Name, Order, SearchValue, - SearchAttribute, MaxListCount, ListStartOffset */ - { "PullvCardListing", "sysyqq", "s", pbap_pull_vcard_listing, - G_DBUS_METHOD_FLAG_ASYNC }, - /* PullPhoneBook input parameters : Name, Filter, Format */ - { "PullvCardEntry", "sty", "s", pbap_pull_vcard_entry, - G_DBUS_METHOD_FLAG_ASYNC }, + { "Select", "ss", "", pbap_select }, { } }; gboolean pbap_register_interface(DBusConnection *connection, const char *path, void *user_data, GDBusDestroyFunction destroy) { + struct session_data *session = user_data; + + session->pbapdata = g_try_malloc0(sizeof(struct pbap_data)); + if (!session->pbapdata) + return FALSE; + return g_dbus_register_interface(connection, path, PBAP_INTERFACE, pbap_methods, NULL, NULL, user_data, destroy); } -void pbap_unregister_interface(DBusConnection *connection, const char *path) +void pbap_unregister_interface(DBusConnection *connection, const char *path, + void *user_data) { + struct session_data *session = user_data; + g_dbus_unregister_interface(connection, path, PBAP_INTERFACE); + if (session->pbapdata) + g_free(session->pbapdata); } diff --git a/obexd/client/pbap.h b/obexd/client/pbap.h index 76d781935..9d902fea5 100644 --- a/obexd/client/pbap.h +++ b/obexd/client/pbap.h @@ -26,6 +26,11 @@ #define PBAP_INTERFACE "org.openobex.PhonebookAccess" +struct pbap_data { + char *path; +}; + gboolean pbap_register_interface(DBusConnection *connection, const char *path, void *user_data, GDBusDestroyFunction destroy); -void pbap_unregister_interface(DBusConnection *connection, const char *path); +void pbap_unregister_interface(DBusConnection *connection, const char *path, + void *user_data); \ No newline at end of file diff --git a/obexd/client/session.c b/obexd/client/session.c index 1f2bb7717..22ba23883 100644 --- a/obexd/client/session.c +++ b/obexd/client/session.c @@ -116,7 +116,7 @@ static void session_unref(struct session_data *session) break; case PBAP_PSE_SVCLASS_ID: pbap_unregister_interface(session->conn, - session->path); + session->path, session); break; } diff --git a/obexd/client/session.h b/obexd/client/session.h index 519153b8c..1af250300 100644 --- a/obexd/client/session.h +++ b/obexd/client/session.h @@ -56,6 +56,7 @@ struct session_data { gchar *owner; /* Session owner */ guint owner_watch; GPtrArray *pending; + void *pbapdata; }; typedef void (*session_callback_t) (struct session_data *session, -- 2.47.3