Diff between 916d09bf045825779a289978d164e2b4eb3d84f7 and c20efca4945395e2c8d1ce1f155abf0be5180db2

Changed Files

File Additions Deletions Status
obexd/plugins/phonebook-tracker.c +79 -14 modified
obexd/plugins/vcard.c +74 -15 modified
obexd/plugins/vcard.h +14 -1 modified

Full Patch

diff --git a/obexd/plugins/phonebook-tracker.c b/obexd/plugins/phonebook-tracker.c
index bff85b8..193226f 100644
--- a/obexd/plugins/phonebook-tracker.c
+++ b/obexd/plugins/phonebook-tracker.c
@@ -43,16 +43,17 @@
 #define TRACKER_RESOURCES_INTERFACE "org.freedesktop.Tracker1.Resources"
 
 #define TRACKER_DEFAULT_CONTACT_ME "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me"
-#define CONTACTS_ID_COL 28
-#define PULL_QUERY_COL_AMOUNT 29
+#define CONTACTS_ID_COL 35
+#define PULL_QUERY_COL_AMOUNT 36
 #define COL_HOME_NUMBER 0
 #define COL_HOME_EMAIL 7
 #define COL_WORK_NUMBER 8
 #define COL_FAX_NUMBER 16
 #define COL_WORK_EMAIL 17
-#define COL_DATE 25
-#define COL_SENT 26
-#define COL_ANSWERED 27
+#define COL_DATE 32
+#define COL_SENT 33
+#define COL_ANSWERED 34
+#define ADDR_FIELD_AMOUNT 7
 
 #define CONTACTS_QUERY_ALL						\
 	"SELECT ?v nco:fullname(?c) "					\
@@ -64,7 +65,9 @@
 	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
 	"nco:birthDate(?c) nco:nickname(?c) nco:websiteUrl(?c) "	\
 	"nco:photo(?c) nco:fullname(?o) nco:department(?a) "		\
-	"nco:role(?a) "							\
+	"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) "		\
+	"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) "	\
+	"nco:postalcode(?pw) nco:country(?pw) "				\
 	"\"NOTACALL\" \"false\" \"false\" ?c "				\
 	"WHERE { "							\
 		"?c a nco:PersonContact . "				\
@@ -84,6 +87,7 @@
 		"?c nco:hasAffiliation ?a . "				\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"}"
@@ -112,7 +116,9 @@
 	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
 	"nco:birthDate(?c) nco:nickname(?c) nco:websiteUrl(?c) "	\
 	"nco:photo(?c) nco:fullname(?o) nco:department(?a) "		\
-	"nco:role(?a) "							\
+	"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) "		\
+	"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) "	\
+	"nco:postalcode(?pw) nco:country(?pw) "				\
 	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
@@ -133,6 +139,7 @@
 		"?c nco:hasAffiliation ?a . "				\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"} ORDER BY DESC(nmo:receivedDate(?call))"
@@ -161,7 +168,9 @@
 	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
 	"nco:birthDate(?c) nco:nickname(?c) nco:websiteUrl(?c) "	\
 	"nco:photo(?c) nco:fullname(?o) nco:department(?a) "		\
-	"nco:role(?a) "							\
+	"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) "		\
+	"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) "	\
+	"nco:postalcode(?pw) nco:country(?pw) "				\
 	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
@@ -182,6 +191,7 @@
 		"?c nco:hasAffiliation ?a . "				\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"} ORDER BY DESC(nmo:receivedDate(?call))"
@@ -210,7 +220,9 @@
 	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew)"	\
 	"nco:birthDate(?c) nco:nickname(?c) nco:websiteUrl(?c) "	\
 	"nco:photo(?c) nco:fullname(?o) nco:department(?a) "		\
-	"nco:role(?a) "							\
+	"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) "		\
+	"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) "	\
+	"nco:postalcode(?pw) nco:country(?pw) "				\
 	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
@@ -230,6 +242,7 @@
 		"?c nco:hasAffiliation ?a . "				\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"} ORDER BY DESC(nmo:sentDate(?call))"
@@ -257,7 +270,9 @@
 	"nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) "	\
 	"nco:birthDate(?c) nco:nickname(?c) nco:websiteUrl(?c) "	\
 	"nco:photo(?c) nco:fullname(?o) nco:department(?a) "		\
-	"nco:role(?a) "							\
+	"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) "		\
+	"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) "	\
+	"nco:postalcode(?pw) nco:country(?pw) "				\
 	"nmo:receivedDate(?call) "					\
 	"nmo:isSent(?call) nmo:isAnswered(?call) ?c "			\
 	"WHERE { "							\
@@ -277,6 +292,7 @@
 	"OPTIONAL { ?c nco:hasAffiliation ?a . "			\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"} UNION { "							\
@@ -295,6 +311,7 @@
 	"OPTIONAL { ?c nco:hasAffiliation ?a . "			\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . } "		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"} } ORDER BY DESC(nmo:receivedDate(?call))"
@@ -329,7 +346,9 @@
 	"nco:postalcode(?p) nco:country(?p) ?f  nco:emailAddress(?ew)"	\
 	"nco:birthDate(<%s>) nco:nickname(<%s>) nco:websiteUrl(<%s>) "	\
 	"nco:photo(<%s>) nco:fullname(?o) nco:department(?a) "		\
-	"nco:role(?a) "							\
+	"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) "		\
+	"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) "	\
+	"nco:postalcode(?pw) nco:country(?pw) "				\
 	"\"NOTACALL\" \"false\" \"false\" <%s> "			\
 	"WHERE { "							\
 		"<%s> a nco:Contact . "					\
@@ -349,6 +368,7 @@
 		"<%s> nco:hasAffiliation ?a . "				\
 		"OPTIONAL { ?a nco:hasPhoneNumber ?w . }" 		\
 		"OPTIONAL { ?a nco:hasEmailAddress ?ew . }"		\
+		"OPTIONAL { ?a nco:hasPostalAddress ?pw . } "		\
 		"OPTIONAL { ?a nco:org ?o . } "				\
 	"} "								\
 	"}"
@@ -721,6 +741,41 @@ static void add_email(struct phonebook_contact *contact, const char *address,
 	contact->emails = g_slist_append(contact->emails, email);
 }
 
+static struct phonebook_address *find_address(GSList *addresses,
+					const char *address, int type)
+{
+	GSList *l;
+
+	for (l = addresses; l; l = l->next) {
+		struct phonebook_address *addr = l->data;
+		if (g_strcmp0(addr->addr, address) == 0 &&
+						addr->type == type)
+			return addr;
+	}
+
+	return NULL;
+}
+
+static void add_address(struct phonebook_contact *contact,
+					const char *address, int type)
+{
+	struct phonebook_address *addr;
+
+	if (address == NULL || address_fields_present(address) == FALSE)
+		return;
+
+	/* Not adding address if there is already added with the same value */
+	if (find_address(contact->addresses, address, type))
+		return;
+
+	addr = g_new0(struct phonebook_address, 1);
+
+	addr->addr = g_strdup(address);
+	addr->type = type;
+
+	contact->addresses = g_slist_append(contact->addresses, addr);
+}
+
 static GString *gen_vcards(GSList *contacts,
 					const struct apparam_field *params)
 {
@@ -753,6 +808,7 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
 	GString *vcards;
 	int last_index, i;
 	gboolean cdata_present = FALSE;
+	char *home_addr, *work_addr;
 
 	DBG("reply %p", reply);
 
@@ -803,9 +859,6 @@ add_entry:
 	contact->additional = g_strdup(reply[4]);
 	contact->prefix = g_strdup(reply[5]);
 	contact->suffix = g_strdup(reply[6]);
-	contact->address = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
-				reply[9], reply[10], reply[11], reply[12],
-				reply[13], reply[14], reply[15]);
 	contact->birthday = g_strdup(reply[18]);
 	contact->nickname = g_strdup(reply[19]);
 	contact->website = g_strdup(reply[20]);
@@ -827,6 +880,18 @@ add_numbers:
 	add_email(contact, reply[COL_HOME_EMAIL], EMAIL_TYPE_HOME);
 	add_email(contact, reply[COL_WORK_EMAIL], EMAIL_TYPE_WORK);
 
+	/* Adding addresses */
+	home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+				reply[9], reply[10], reply[11], reply[12],
+				reply[13], reply[14], reply[15]);
+
+	work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+				reply[25], reply[26], reply[27], reply[28],
+				reply[29], reply[30], reply[31]);
+
+	add_address(contact, home_addr, ADDR_TYPE_HOME);
+	add_address(contact, work_addr, ADDR_TYPE_WORK);
+
 	DBG("contact %p", contact);
 
 	/* Adding contacts data to wrapper struct - this data will be used to
diff --git a/obexd/plugins/vcard.c b/obexd/plugins/vcard.c
index 33a1ede..6d74e06 100644
--- a/obexd/plugins/vcard.c
+++ b/obexd/plugins/vcard.c
@@ -156,21 +156,20 @@ static gboolean contact_fields_present(struct phonebook_contact * contact)
 	return FALSE;
 }
 
-static gboolean address_fields_present(struct phonebook_contact *contact)
+gboolean address_fields_present(const char *address)
 {
-	gchar **address_fields = g_strsplit(contact->address, ";",
-							ADDR_FIELD_AMOUNT);
-	int i = 0;
+	gchar **fields = g_strsplit(address, ";", ADDR_FIELD_AMOUNT);
+	int i;
 
-	for (; i < ADDR_FIELD_AMOUNT; ++i) {
+	for (i = 0; i < ADDR_FIELD_AMOUNT; ++i) {
 
-		if (strlen(address_fields[i]) != 0) {
-			g_strfreev(address_fields);
+		if (strlen(fields[i]) != 0) {
+			g_strfreev(fields);
 			return TRUE;
 		}
 	}
 
-	g_strfreev(address_fields);
+	g_strfreev(fields);
 
 	return FALSE;
 }
@@ -376,15 +375,54 @@ static void vcard_printf_org(GString *vcards,
 				contact->department, contact->title);
 }
 
-static void vcard_printf_adr(GString *vcards,
-					struct phonebook_contact *contact)
+static void vcard_printf_address(GString *vcards, uint8_t format,
+					const char *address,
+					enum phonebook_address_type category)
 {
-	if (address_fields_present(contact) == FALSE) {
+	char buf[LEN_MAX];
+	char field[ADDR_FIELD_AMOUNT][LEN_MAX];
+	const char *category_string = "";
+	int len, i;
+	gchar **address_fields;
+
+	if (!address || address_fields_present(address) == FALSE) {
 		vcard_printf(vcards, "ADR:");
 		return;
 	}
 
-	vcard_printf(vcards, "ADR:%s", contact->address);
+	switch (category) {
+	case ADDR_TYPE_HOME:
+		if (format == FORMAT_VCARD21)
+			category_string = "HOME";
+		else if (format == FORMAT_VCARD30)
+			category_string = "TYPE=HOME";
+		break;
+	case ADDR_TYPE_WORK:
+		if (format == FORMAT_VCARD21)
+			category_string = "WORK";
+		else if (format == FORMAT_VCARD30)
+			category_string = "TYPE=WORK";
+		break;
+	default:
+		if (format == FORMAT_VCARD21)
+			category_string = "OTHER";
+		else if (format == FORMAT_VCARD30)
+			category_string = "TYPE=OTHER";
+		break;
+	}
+
+	address_fields = g_strsplit(address, ";", ADDR_FIELD_AMOUNT);
+
+	for (i = 0; i < ADDR_FIELD_AMOUNT; ++i) {
+		len = strlen(address_fields[i]);
+		add_slash(field[i], address_fields[i], LEN_MAX, len);
+	}
+
+	snprintf(buf, LEN_MAX, "%s;%s;%s;%s;%s;%s;%s",
+	field[0], field[1], field[2], field[3], field[4], field[5], field[6]);
+	g_strfreev(address_fields);
+
+	vcard_printf(vcards,"ADR;%s:%s", category_string, buf);
 }
 
 static void vcard_printf_datetime(GString *vcards,
@@ -465,8 +503,19 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 		}
 	}
 
-	if (filter & FILTER_ADR)
-		vcard_printf_adr(vcards, contact);
+	if (filter & FILTER_ADR) {
+		GSList *l = contact->addresses;
+
+		if (g_slist_length(l) == 0)
+			vcard_printf_address(vcards, format, NULL,
+							ADDR_TYPE_OTHER);
+
+		for (; l; l = l->next) {
+			struct phonebook_address *addr = l->data;
+			vcard_printf_address(vcards, format, addr->addr,
+								addr->type);
+		}
+	}
 
 	if (filter & FILTER_BDAY)
 		vcard_printf_tag(vcards, format, "BDAY", NULL,
@@ -509,6 +558,14 @@ static void email_free(gpointer data, gpointer user_data)
 	g_free(email);
 }
 
+static void address_free(gpointer data, gpointer user_data)
+{
+	struct phonebook_address *addr = data;
+
+	g_free(addr->addr);
+	g_free(addr);
+}
+
 void phonebook_contact_free(struct phonebook_contact *contact)
 {
 	if (contact == NULL)
@@ -520,13 +577,15 @@ void phonebook_contact_free(struct phonebook_contact *contact)
 	g_slist_foreach(contact->emails, email_free, NULL);
 	g_slist_free(contact->emails);
 
+	g_slist_foreach(contact->addresses, address_free, NULL);
+	g_slist_free(contact->addresses);
+
 	g_free(contact->fullname);
 	g_free(contact->given);
 	g_free(contact->family);
 	g_free(contact->additional);
 	g_free(contact->prefix);
 	g_free(contact->suffix);
-	g_free(contact->address);
 	g_free(contact->birthday);
 	g_free(contact->nickname);
 	g_free(contact->website);
diff --git a/obexd/plugins/vcard.h b/obexd/plugins/vcard.h
index b1e971e..d012106 100644
--- a/obexd/plugins/vcard.h
+++ b/obexd/plugins/vcard.h
@@ -40,6 +40,12 @@ enum phonebook_call_type {
 	CALL_TYPE_OUTGOING,
 };
 
+enum phonebook_address_type {
+	ADDR_TYPE_HOME,
+	ADDR_TYPE_WORK,
+	ADDR_TYPE_OTHER,
+};
+
 struct phonebook_number {
 	char *tel;
 	int type;
@@ -50,6 +56,11 @@ struct phonebook_email {
 	int  type;
 };
 
+struct phonebook_address {
+	char *addr;
+	int type;
+};
+
 struct phonebook_contact {
 	char *fullname;
 	char *given;
@@ -59,7 +70,7 @@ struct phonebook_contact {
 	GSList *emails;
 	char *prefix;
 	char *suffix;
-	char *address;
+	GSList *addresses;
 	char *birthday;
 	char *nickname;
 	char *website;
@@ -75,3 +86,5 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 					uint64_t filter, uint8_t format);
 
 void phonebook_contact_free(struct phonebook_contact *contact);
+
+gboolean address_fields_present(const char *address);