Diff between 44090d52112f25d1f97d5657609f0a4ed93b69b5 and 75d32c6b3a3bddaad19b7880950f9a503afe652b

Changed Files

File Additions Deletions Status
obexd/client/pbap.c +130 -26 modified
obexd/client/pbap.h +6 -1 modified
obexd/client/session.c +1 -1 modified
obexd/client/session.h +1 -0 modified

Full Patch

diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c
index e29d3c9..4a536d6 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 76d7819..9d902fe 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 1f2bb77..22ba238 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 519153b..1af2503 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,