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
#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) " \
"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 . " \
"?c nco:hasAffiliation ?a . " \
"OPTIONAL { ?a nco:hasPhoneNumber ?w . } " \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
"OPTIONAL { ?a nco:org ?o . } " \
"} " \
"}"
"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 { " \
"?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))"
"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 { " \
"?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))"
"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 { " \
"?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))"
"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 { " \
"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 { " \
"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))"
"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 . " \
"<%s> nco:hasAffiliation ?a . " \
"OPTIONAL { ?a nco:hasPhoneNumber ?w . }" \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . }" \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
"OPTIONAL { ?a nco:org ?o . } " \
"} " \
"}"
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)
{
GString *vcards;
int last_index, i;
gboolean cdata_present = FALSE;
+ char *home_addr, *work_addr;
DBG("reply %p", reply);
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]);
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
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;
}
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,
}
}
- 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,
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)
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
CALL_TYPE_OUTGOING,
};
+enum phonebook_address_type {
+ ADDR_TYPE_HOME,
+ ADDR_TYPE_WORK,
+ ADDR_TYPE_OTHER,
+};
+
struct phonebook_number {
char *tel;
int type;
int type;
};
+struct phonebook_address {
+ char *addr;
+ int type;
+};
+
struct phonebook_contact {
char *fullname;
char *given;
GSList *emails;
char *prefix;
char *suffix;
- char *address;
+ GSList *addresses;
char *birthday;
char *nickname;
char *website;
uint64_t filter, uint8_t format);
void phonebook_contact_free(struct phonebook_contact *contact);
+
+gboolean address_fields_present(const char *address);