Diff between e86c39c0abd503cad0ff63900c5ff2bf8c77039f and 387deddcbfad9e917a927a239eda17e516c2607b

Changed Files

File Additions Deletions Status
obexd/plugins/phonebook-tracker.c +89 -28 modified
obexd/plugins/vcard.c +33 -11 modified
obexd/plugins/vcard.h +6 -2 modified

Full Patch

diff --git a/obexd/plugins/phonebook-tracker.c b/obexd/plugins/phonebook-tracker.c
index a2611a1..e0cf65a 100644
--- a/obexd/plugins/phonebook-tracker.c
+++ b/obexd/plugins/phonebook-tracker.c
@@ -43,142 +43,189 @@
 #define TRACKER_DEFAULT_CONTACT_ME "<urn:nco:default-contact-me>"
 
 #define CONTACTS_QUERY_ALL						\
-	"SELECT nco:hasPhoneNumber(?c) nco:fullname(?c) "		\
+	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
 	"nco:nameFamily(?c) nco:nameGiven(?c) "				\
 	"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) "		\
 	"nco:nameHonorificSuffix(?c) nco:hasEmailAddress(?c) "		\
+	"nco:phoneNumber(?w) "						\
 	"WHERE { "							\
-	"	?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+	"OPTIONAL { "							\
+		"?c nco:hasAffiliation ?a . "				\
+		"?a nco:hasPhoneNumber ?w . "				\
+	"} "								\
 	"}"
 
 #define CONTACTS_QUERY_ALL_LIST						\
 	"SELECT nco:contactUID(?c) nco:nameFamily(?c) "			\
 	"nco:nameGiven(?c) nco:nameAdditional(?c) "			\
 	"nco:nameHonorificPrefix(?c) nco:nameHonorificSuffix(?c) "	\
-	"nco:hasPhoneNumber(?c) "					\
+	"nco:phoneNumber(?h) "						\
 	"WHERE { "							\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
 	"}"
 
 #define MISSED_CALLS_QUERY						\
-	"SELECT nco:hasPhoneNumber(?c) nco:fullname(?c) "		\
+	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
 	"nco:nameFamily(?c) nco:nameGiven(?c) "				\
 	"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) "		\
 	"nco:nameHonorificSuffix(?c) nco:hasEmailAddress(?c) "		\
+	"nco:phoneNumber(?w) "						\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
 		"nmo:isSent false ; "					\
 		"nmo:isAnswered false ."				\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+	"OPTIONAL { "							\
+		"?c nco:hasAffiliation ?a . "				\
+		"?a nco:hasPhoneNumber ?w . "				\
+	"} "								\
 	"}"
 
 #define MISSED_CALLS_LIST						\
 	"SELECT nco:contactUID(?c) nco:nameFamily(?c) "			\
 	"nco:nameGiven(?c) nco:nameAdditional(?c) "			\
 	"nco:nameHonorificPrefix(?c) nco:nameHonorificSuffix(?c) "	\
-	"nco:hasPhoneNumber(?c) "					\
+	"nco:phoneNumber(?h) "						\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
 		"nmo:isSent false ; "					\
 		"nmo:isAnswered false ."				\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
 	"}"
 
 #define INCOMING_CALLS_QUERY						\
-	"SELECT nco:hasPhoneNumber(?c) nco:fullname(?c) "		\
+	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
 	"nco:nameFamily(?c) nco:nameGiven(?c) "				\
 	"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) "		\
 	"nco:nameHonorificSuffix(?c) nco:hasEmailAddress(?c) "		\
+	"nco:phoneNumber(?w) "						\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
 		"nmo:isSent false . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+	"OPTIONAL { "							\
+		"?c nco:hasAffiliation ?a . "				\
+		"?a nco:hasPhoneNumber ?w . "				\
+	"} "								\
 	"}"
 
 #define INCOMING_CALLS_LIST						\
 	"SELECT nco:contactUID(?c) nco:nameFamily(?c) "			\
 	"nco:nameGiven(?c) nco:nameAdditional(?c) "			\
 	"nco:nameHonorificPrefix(?c) nco:nameHonorificSuffix(?c) "	\
-	"nco:hasPhoneNumber(?c) "					\
+	"nco:phoneNumber(?h) "						\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
 		"nmo:isSent false . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
 	"}"
 
 #define OUTGOING_CALLS_QUERY						\
-	"SELECT nco:hasPhoneNumber(?c) nco:fullname(?c) "		\
+	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
 	"nco:nameFamily(?c) nco:nameGiven(?c) "				\
 	"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) "		\
 	"nco:nameHonorificSuffix(?c) nco:hasEmailAddress(?c) "		\
+	"nco:phoneNumber(?w) "						\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:to ?c ; "						\
 		"nmo:isSent true . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+	"OPTIONAL { "							\
+		"?c nco:hasAffiliation ?a . "				\
+		"?a nco:hasPhoneNumber ?w . "				\
+	"} "								\
 	"}"
 
 #define OUTGOING_CALLS_LIST						\
 	"SELECT nco:contactUID(?c) nco:nameFamily(?c) "			\
 	"nco:nameGiven(?c) nco:nameAdditional(?c) "			\
 	"nco:nameHonorificPrefix(?c) nco:nameHonorificSuffix(?c) "	\
-	"nco:hasPhoneNumber(?c) "					\
+	"nco:phoneNumber(?h) "						\
 	"WHERE { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:to ?c ; "						\
 		"nmo:isSent true . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
 	"}"
 
 #define COMBINED_CALLS_QUERY						\
-	"SELECT nco:hasPhoneNumber(?c) nco:fullname(?c) "		\
+	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
 	"nco:nameFamily(?c) nco:nameGiven(?c) "				\
 	"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) "		\
 	"nco:nameHonorificSuffix(?c) nco:hasEmailAddress(?c) "		\
+	"nco:phoneNumber(?w) "						\
 	"WHERE { "							\
 	"{ "								\
 		"?call a nmo:Call ; "					\
 		"nmo:to ?c ; "						\
 		"nmo:isSent true . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+		"OPTIONAL { "						\
+			"?c nco:hasAffiliation ?a . "			\
+			"?a nco:hasPhoneNumber ?w . "			\
+		"} "							\
 	"} UNION { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
 		"nmo:isSent false . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+		"OPTIONAL { "						\
+			"?c nco:hasAffiliation ?a . "			\
+			"?a nco:hasPhoneNumber ?w . "			\
+		"} "							\
 	"} } "
 
 #define COMBINED_CALLS_LIST						\
 	"SELECT nco:contactUID(?c) nco:nameFamily(?c) "			\
 	"nco:nameGiven(?c) nco:nameAdditional(?c) "			\
 	"nco:nameHonorificPrefix(?c) nco:nameHonorificSuffix(?c) "	\
-	"nco:hasPhoneNumber(?c) "					\
+	"nco:phoneNumber(?h) "						\
 	"WHERE { "							\
 	"{ "								\
 		"?call a nmo:Call ; "					\
 		"nmo:to ?c ; "						\
 		"nmo:isSent true . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
 	"} UNION { "							\
 		"?call a nmo:Call ; "					\
 		"nmo:from ?c ; "					\
 		"nmo:isSent false . "					\
-		"?c a nco:PersonContact . "				\
+		"?c a nco:PersonContact ; "				\
+		"nco:hasPhoneNumber ?h . "				\
 	"} } "
 
 
 #define CONTACTS_QUERY_FROM_URI						\
-	"SELECT nco:hasPhoneNumber(?c) nco:fullname(?c) "		\
+	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
 	"nco:nameFamily(?c) nco:nameGiven(?c) nco:nameAdditional(?c) "	\
 	"nco:nameHonorificPrefix(?c) nco:nameHonorificSuffix(?c)  "	\
 	"nco:hasEmailAddress(?c) "					\
+	"nco:phoneNumber(?w) "						\
 	"WHERE { "							\
 		"?c a nco:PersonContact ; "				\
-		"nco:contactUID <%s> . "				\
+		"nco:contactUID <%s> ; "				\
+		"nco:hasPhoneNumber ?h . "				\
+	"OPTIONAL { "							\
+		"?c nco:hasAffiliation ?a . "				\
+		"?a nco:hasPhoneNumber ?w . "				\
+	"} "								\
 	"}"
 
 typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
@@ -399,6 +446,7 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
 	struct phonebook_data *data = user_data;
 	const struct apparam_field *params = data->params;
 	struct phonebook_contact *contact;
+	struct phonebook_number *number;
 	GString *vcards = data->vcards;
 	int last_index;
 
@@ -424,8 +472,6 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
 
 add_entry:
 	contact = g_new0(struct phonebook_contact, 1);
-	contact->tel = g_strdup(reply[0]);
-	contact->tel_type = 1; /* HOME */
 	contact->fullname = g_strdup(reply[1]);
 	contact->family = g_strdup(reply[2]);
 	contact->given = g_strdup(reply[3]);
@@ -434,6 +480,21 @@ add_entry:
 	contact->suffix = g_strdup(reply[6]);
 	contact->email = g_strdup(reply[7]);
 
+	number = g_new0(struct phonebook_number, 1);
+	number->tel = g_strdup(reply[0]);
+	number->type = 0; /* HOME */
+
+	contact->numbers = g_slist_append(contact->numbers, number);
+
+	/* Has WORK Phonenumber */
+	if (strlen(reply[8])) {
+		number = g_new0(struct phonebook_number, 1);
+		number->tel = g_strdup(reply[8]);
+		number->type = 3; /* WORK */
+
+		contact->numbers = g_slist_append(contact->numbers, number);
+	}
+
 	DBG("contact %p", contact);
 
 	phonebook_add_contact(vcards, contact, params->filter, params->format);
@@ -582,7 +643,7 @@ int phonebook_pull(const char *name, const struct apparam_field *params,
 	data->user_data = user_data;
 	data->cb = cb;
 
-	return query_tracker(query, 8, pull_contacts, data);
+	return query_tracker(query, 9, pull_contacts, data);
 }
 
 int phonebook_get_entry(const char *folder, const char *id,
@@ -604,7 +665,7 @@ int phonebook_get_entry(const char *folder, const char *id,
 
 	query = g_strdup_printf(CONTACTS_QUERY_FROM_URI, id);
 
-	ret = query_tracker(query, 8, pull_contacts, data);
+	ret = query_tracker(query, 9, pull_contacts, data);
 
 	g_free(query);
 
diff --git a/obexd/plugins/vcard.c b/obexd/plugins/vcard.c
index 4afa12f..0bd2052 100644
--- a/obexd/plugins/vcard.c
+++ b/obexd/plugins/vcard.c
@@ -208,9 +208,8 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 					uint64_t filter, uint8_t format)
 {
 	/* There's really nothing to do */
-	if ((contact->tel == NULL || contact->tel[0] == '\0') &&
-					(contact->fullname == NULL ||
-					contact->fullname[0] == '\0'))
+	if ((contact->numbers == NULL && (contact->fullname == NULL ||
+						contact->fullname[0] == '\0')))
 		return;
 
 	if (format == FORMAT_VCARD30)
@@ -221,15 +220,28 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 	vcard_printf_begin(vcards, format);
 
 	if (filter & FILTER_FN) {
-		if (contact->fullname == NULL || contact->fullname[0] == '\0')
-			vcard_printf_fullname(vcards, contact->tel);
-		else
-			vcard_printf_fullname(vcards, contact->fullname);
+		char* fullname;
+		if (contact->fullname == NULL || contact->fullname[0] == '\0') {
+			struct phonebook_number *number;
+
+			number = contact->numbers->data;
+			fullname = number->tel;
+		} else
+			fullname = contact->fullname;
+
+		vcard_printf_fullname(vcards, fullname);
 	}
 
-	if (filter & FILTER_TEL)
-		vcard_printf_number(vcards, contact->tel, contact->tel_type,
-				TEL_TYPE_OTHER);
+	if (filter & FILTER_TEL) {
+		GSList *l;
+
+		for (l = contact->numbers; l; l = l->next) {
+			struct phonebook_number *number = l->data;
+
+			vcard_printf_number(vcards, number->tel, 1,
+								number->type);
+		}
+	}
 
 	if (filter & FILTER_N)
 		vcard_printf_name(vcards, contact);
@@ -240,16 +252,26 @@ void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
 	vcard_printf_end(vcards);
 }
 
+static void number_free(gpointer data, gpointer user_data)
+{
+	struct phonebook_number *number = data;
+
+	g_free(number->tel);
+	g_free(number);
+}
+
 void phonebook_contact_free(struct phonebook_contact *contact)
 {
 	if (contact == NULL)
 		return;
 
+	g_slist_foreach(contact->numbers, number_free, NULL);
+	g_slist_free(contact->numbers);
+
 	g_free(contact->fullname);
 	g_free(contact->given);
 	g_free(contact->family);
 	g_free(contact->additional);
-	g_free(contact->tel);
 	g_free(contact->email);
 	g_free(contact->prefix);
 	g_free(contact->suffix);
diff --git a/obexd/plugins/vcard.h b/obexd/plugins/vcard.h
index 5362a66..45b82d7 100644
--- a/obexd/plugins/vcard.h
+++ b/obexd/plugins/vcard.h
@@ -27,13 +27,17 @@ enum phonebook_number_type {
 	TEL_TYPE_OTHER,
 };
 
+struct phonebook_number {
+	char *tel;
+	int type;
+};
+
 struct phonebook_contact {
 	char *fullname;
 	char *given;
 	char *family;
 	char *additional;
-	char *tel;
-	int tel_type;
+	GSList *numbers;
 	char *email;
 	char *prefix;
 	char *suffix;