From 387deddcbfad9e917a927a239eda17e516c2607b Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Wed, 19 May 2010 17:29:54 -0300 Subject: [PATCH] obexd: Add support for multiple telephone numbers --- obexd/plugins/phonebook-tracker.c | 117 +++++++++++++++++++++++------- obexd/plugins/vcard.c | 44 ++++++++--- obexd/plugins/vcard.h | 8 +- 3 files changed, 128 insertions(+), 41 deletions(-) diff --git a/obexd/plugins/phonebook-tracker.c b/obexd/plugins/phonebook-tracker.c index a2611a1bb..e0cf65adf 100644 --- a/obexd/plugins/phonebook-tracker.c +++ b/obexd/plugins/phonebook-tracker.c @@ -43,142 +43,189 @@ #define TRACKER_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 4afa12f36..0bd2052f3 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 5362a66d6..45b82d74a 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; -- 2.47.3